perm filename SAILSP.MAN[RUT,LSP]3 blob
sn#380270 filedate 1978-09-12 generic text, type T, neo UTF8
STANFORD ARTIFICIAL INTELLIGENCE LABORATORY
OPERATING NOTE 28.7
STANFORD LISP 1.6 MANUAL
by
Lynn H. Quam and Whitfield Diffie
ABSTRACT: This manual describes the PDP-10 LISP 1.6 system developed
by the Stanford Artificial Intelligence Project. The
manual is not a tutorial on LISP but is intended to
supplement existing LISP tutorials in order to prepare one
to understand and use this LISP system.
This work was supported by the Advanced Research Projects Agency of
the Department of Defense under Contract SD-183.
The views and conclusions contained in this document are those of the
authors and should not be interpreted as necessarily representing the
official policies, either expressed or implied, of the Advanced
Research Projects Agency or the U.S. Government.
SAILON 28.7 LISP i
PREFACE
This manual is the result of several relatively minor changes
and additions to SAILON 28.4. It supercedes and replaces SAILONS 1,
4, 28.2-4, and 41.
The changes reflect changes in LISP and may be summarized as
follows:
LISP initialization has changed; Section 2.1.
There are some new debugging facilities in Appendix N and the
documentation for some old ones has been put into the manual.
The compiler has been revised, and is described in a greatly
expanded Appendix F.
(*** Minor modifications to LISP 1.6 which were made when
converting the system to UCI LISP have been incorporated into this
manual. Major modifications are described in the UCI LISP Manual and
the Rutgers ILISP documentation. - R. LeFaivre, 9/15/76)
SAILON 28.7 LISP ii
Acknowledgment
The STANFORD A.I. Lisp 1.6 System was originally an
adaptation of one developed by the Artificial Intelligence Project at
M.I.T. Since 1966, that system has been largely rewritten by John
Allen and Lynn Quam.
John R. Allen implemented the storage reallocation system
which makes it possible for the user to change the sizes of the
various memory spaces. He also designed and coded the editor ALVINE,
wrote the first loader interface, and generally maintained and
debugged the system. John Allen contributed the ALVINE
documentation in Appendix A.
Marilyn Mullins has assisted in the preparation of the
present edition.
SAILON 28.7 LISP iii
TABLE OF CONTENTS
Page
Preface................................................. i
Acknowledgment ......................................... ii
Table of Contents....................................... iii
CHAPTER
1. INTRODUCTION...................................... 1-1
1.1 Guide to the Novice........................... 1-1
1.2 Guide to the User Experienced with Another
LISP System............................. 1-2
1.1 Guide to Useful Functions and Features........ 1-3
1.4 Document Conventions.......................... 1-4
2. INTERACTIVE USE OF THE SYSTEM .................... 2-1
2.1 Using the System ............................. 2-1
2.2 Special Teletype Control Characters........... 2-1
3. IDENTIFIERS ...................................... 3-1
3.1 Property Lists................................ 3-2
3.2 The OBLIST.................................... 3-3
3.3 Strings....................................... 3-3
4. NUMBERS............................................ 4-1
4.1 Integers...................................... 4-1
4.2 Reals......................................... 4-3
5. S-EXPRESSIONS...................................... 5-1
6. LAMBDA EXPRESSIONS................................. 6-1
6.1 EXPRs and SUBRs............................... 6-2
6.2 FEXPRs AND FSUBRs............................. 6-2
6.3 LEXPRs AND LSUBRs............................. 6-2
6.4 MACROs........................................ 6-3
7. EVALUATION OF S-EXPRESSIONS........................ 7-1
7.1 Variable Bindings............................. 7-2
7.2 The A-LIST and FUNARG Features................ 7-3
8. CONDITIONAL EXPRESSIONS............................ 8-1
SAILON 28.7 LISP iv
9. PREDICATES......................................... 9-1
9.1 S-Expression Predicates....................... 9-2
9.2 Numerical Predicates.......................... 9-2
9.3 Boolean Predicates............................ 9-3
10. FUNCTIONS ON S-EXPRESSIONS.........................10-1
10.1 S-Expression Building Functions...............10-1
10.2 S-Expression Fragmenting Functions............10-2
10.3 S-Expression Modifying Functions.............10-2
10.4 S-Expression Transforming Functions...........10-4
10.5 S-Expression Mapping Functions................10-4
10.6 S-Expression Searching Functions..............10-6
10.7 Character List Transforming Functions.........10-7
11. FUNCTIONS ON IDENTIFIERS...........................11-1
11.1 Property List Functions.......................11-1
11.2 OBLIST Functions..............................11-2
11.3 Identifier Creating Functions.................11-3
12. FUNCTIONS ON NUMBERS...............................12-1
12.1 Arithmetic Functions..........................12-1
12.2 Logical Functions.............................12-2
13. PROGRAMS...........................................13-1
14. INPUT/OUTPUT.......................................14-1
14.1 File Names....................................14-1
14.2 Channel Names.................................14-1
14.3 Input.........................................14-1
14.4 Output........................................14-4
15. ARRAYS.............................................15-1
15.1 Examine and Deposit...........................15-2
16. OTHER FUNCTIONS....................................16-1
APPENDIX A. ALVINE - by John Allen..................... A-1
APPENDIX B. ERROR MESSAGES............................. B-1
APPENDIX C. MEMORY ALLOCATION.......................... C-1
APPENDIX D. GARBAGE COLLECTION......................... D-1
APPENDIX E. COMPILED FUNCTION LINKAGE AND ACCUMULATOR
USAGE................................... E-1
APPENDIX F. THE LISP COMPILER.......................... F-1
APPENDIX G. THE LISP ASSEMBLER - LAP................... G-1
APPENDIX H. THE LOADER................................. H-1
APPENDIX I. BIGNUMS - ARBITRARY PRECISION INTEGERS..... I-1
SAILON 28.7 LISP v
APPENDIX J. A USER MODIFIABLE LISP SCANNER............. J-1
APPENDIX K. SOS-LINK................................... K-1
APPENDIX L. SOME DIFFERENCES BETWEEN THIS AND OTHER
LISPS................................... L-1
REFERENCES.............................................REF-1
INDEX..................................................IND-1
SAILON 28.7 CHAPTER 1 1-1
CHAPTER 1
INTRODUCTION
This manual is intended to explain the interactive LISP 1.6
system which has been developed for the PDP-10 at the Stanford
University Artificial Intelligence Project. It is assumed that the
reader is familiar with either some other LISP system or the LISP 1.5
PRIMER by Clark Weissman[2].
The LISP 1.6 system described has as a subset most of the
features and functions of other LISP 1.5 systems. In addition, there
are several new features such as an arbitrary precision integer
package, an S-expression editor, up to 14 active input-output
channels, the ability to control the size of memory spaces, a
standard relocating loader to load assembly language or compiled
programs, etc.
This system uses an interpreter; however, there is also a
compiler which produces machine code. Compiled functions are
approximately 20 times as fast and take less memory space.
This manual is organized in a functional manner. First the
basic data structures are described; then the functions for operating
on them. The appendices present more detailed information on the
system, its internal structure, the compiler, and several auxiliary
packages.
SAILON 28.7 CHAPTER 1 1-2
1.1 Guide to the Novice
The user who is not experienced with any LISP system is
advised to follow the instructions below:
1) Become familiar with Weissman's LISP 1.6 Primer[2] or some
equivalent introductory LISP Manual.
2) Learn the document conventions (1.4).
3) Become superficially familiar with LISP 1.6 identifiers,
numbers and S-expressions (Chapters 3,4, and 5).
4) Understand the most useful functions: Those preceded by
exclamation marks "!" in chapters 6 through 14.
5) Learn how to define functions (6.1).
6) Learn how to interact with LISP (Chapter 2).
7) Try some examples. Weissman[1] has some good problems.
8) Learn what other useful functions and features are
available (1.3).
1.2 Guide to the User Experienced with Another LISP System
The user who has used another LISP system is advised to
follow these instructions:
1) Learn the document conventions (1.4).
2) Learn top level of LISP 1.6 is EVAL, not EVALQUOTE.
3) Use DE, DF and DEFPROP for defining functions. (Section
11.1).
4) Many functions differ from those in other systems. Most
of these are noted in the index.
5) The syntax of atoms is different from other systems
(Chapters 3 and 4).
6) Learn how to interact with LISP (Chapter 2).
7) Try some examples.
8) Learn what other useful functions and features are
available (1.3).
SAILON 28.7 CHAPTER 1 1-3
1.3 Guide to Useful Functions and Features
The following is a partial list of useful features and functions in
LISP 1.6 and what they might be useful for.
1) READ has some very useful control characters (Section 14.3).
2) Input/Output (Chapter 14) is very flexible.
3) One can control error messages (Chapter 16).
4) There is a LISP compiler (Appendix F) which generates code
that runs approximately twenty times as fast as interpreted
functions.
5) One can load and link LISP to assembly and Fortran compiled
programs. See Appendix H.
6) One can have files automatically loaded by use of the file
INIT.LSP which is automatically loaded on entry.
SAILON 28.7 Document Conventions 1.4-1
1.4 Document Conventions
1.4.1 Representation Conventions
In the description of data structures, the following
notational conventions will be used.
←←←←←←←←←←←←←←←←← represents a 36-bit word in
| | | FREE STORAGE with 2 18-bit
| | |-> pointers.
|←←←←←←←|←←←←←←←|
|
←←←←←←←←←←←←←←←←← represents the last word in
| | | a list.
| | NIL |
|←←←←←←←|←←←←←←←|
|
←←←←←←←←←←←←←←←←← represents a 36-bit word in
| | FULL WORD SPACE.
| |
|←←←←←←←←←←←←←←←|
1.4.2 Syntax Conventions
A slightly modified form of BNF is used to define syntax
equations. Optional terms are surrounded by curly brackets { and }.
1.4.3 Calling Sequence Conventions
Calling sequences to LISP functions are presented in
S-expression form, with the CAR of the S-expression being the name of
the function. An argument to a function is evaluated unless that
argument is surrounded by quotes (") in the calling sequence
definition. Quotes mean that the function implicitly QUOTEs that
argument.
Examples: (SETQ "ID" V) ID is not evaluated, but V is
evaluated.
(QUOTE "V") V is not evaluated.
1.4.4 Other Conventions
The blank character (ASCII 40) is indicated by "←" when
appropriate for clarity. The delimiters altmode, carriage return,
linefeed and space will sometimes be represented as <alt>, <cr>, <lf>
and <sp>.
SAILON 28.7 Document Conventions 1.4-2
A special notation in the left margin is used to indicate the
degree of utility or difficulty of each section of this manual:
mark meaning
! basic
<no mark> generally useful
* useful but more sophisticated
# not generally useful
SAILON 28.7 CHAPTER 2 2-1
CHAPTER 2
INTERACTIVE USE OF THE SYSTEM
2.1 Using the System
The following dialog shows how to log into the time sharing
system, start the LISP system, and interact with the top level of
LISP. The period, sharp sign and askerisk are typed by the system,
login and lisp respectively to indicate that they are waiting for the
user to type.
.L (*** This procedure is somewhat different
#1,FOO in UCI LISP. Note that UCI LISP is called
↑C ILISP instead of LISP.)
.R LISP 20 This give a 20K Lisp instead of the usual 12K.
ALLOC? Y Indicates that the user will specify
the sizes of the various spaces.
FULL WDS=<sp> This gives the default value.
BIN.PROG.SP=12000<sp> This gives 12K of Binary Program Space.
SPEC.PDL=<sp> This give the default value.
SPEC.PDL=2000<sp> Gives 2K of regular push down list.
HASH=177<sp> Makes the length of the OBLIST 177.
For a full discussion of allocation see Appendix C.
Digression:
At this point, after allocation and before anything else, the
file LISP.LSP is read from the system. This defines various macros,
recent additions to the system, bootstrap definitions for the
functions in the various self loading utility files, Trace, SOSLNK,
LAP etc. In addition, if there is a file by the name INIT.LSP in the
user's directory, it will be loaded too. This enables the user to
have anything he likes loaded automatically.
To continue:
*T<alt>
T T and NIL always evaluate to themselves.
*(QUOTE (A B C))<cr>
(A B C) Value of QUOTE
*(CONS 1 (QUOTE A))<cr>
(1 . A) Numbers always evaluate to themselves
and thus need not be quoted.
*(DSKIN <random file name>)<cr> Reads and evaluates each expression
in the file.
<a long sequence of output> This output can be suppressed with ↑O.
SAILON 28.7 CHAPTER 2 2-2
*(DEFPROP CDRQ (LAMBDA (L) (CDAR L)) FEXPR)<cr>
CDRQ
*(CDRQ CAR)<cr>
(SUBR #address PNAME (#fullword))
*(DE TWICE (NUM) (TIMES 2 NUM))<cr>
TWICE
*(TWICE 3)<cr>
6
<etc.>
2.2 Special Teletype Control Characters
The time-sharing system treats many control characters in special
ways. For a complete discussion of control characters see the PDP-10
TIME SHARING MONITOR MANUAL. Briefly, the following special control
characters are used in LISP.
Teletype III Display Meaning
↑C CALL Stop the job and talk to
time-sharing system.
↑O Control 2 Suppress console printout
linefeed until an input is requested.
↑U Control 1 Delete the entire input
linefeed line now being typed.
(Only with (DDTIN NIL)).
↑G(BELL) π Stop the LISP interpreter
and return control to the
top level of LISP. Only
effective when LISP is
asking for console input.
See INITFN (16).
rubout BS Delete the last character
typed. (For (DDTIN T) see
14-3.
SAILON 28.7 CHAPTER 3 3-1
CHAPTER 3
IDENTIFIERS
Identifiers are strings of characters which taken together
represent a single atomic quantity.
Syntax:
<comments> ::=<ASCII 31> <any sequence of characters not
including line-feed> <line feed>
<delimiter> ::= (|) | [|] | ? |@|/|"| <blank> | <altmode> |
carriage-return | <line-feed> | <tab> | <form-
feed>
<character>::= <any extended ASCII character other than null
and ASCII 176>
<digit>::= 0|1|2|3|4|5|6|7|8|9
<letter>::= <any character not a digit and not a delimiter>
<identifier>::= <letter>
::=<identifier> <digit>
::= / <character>
::= <identifier>/<character>
Semantics:
Identifiers are normally strings of characters beginning with
a letter and followed by letters and digits. It is sometimes
convenient to create identifiers which contain delimiters or begin
with digits. The use of the delimiter "/" (slash) causes the
following character be taken literally, and the slash itself is not
part of the identifier. Thus, /AB is the same as AB is the same as
/A/B.
Comments are useful for allowing descriptive text in files
which will be completely ignored when read. Comments also make it
possible to extend atoms (identifiers, strings and numbers) across
line boundaries without any of the characters in the comment becoming
part of the atom.
(*** The comment character in UCI LISP is ASCII 31 (↑Y).
The old LISP 1.6 comment character of ASCII 32 (↑Z) is also
recognized.)
Examples: A /(
a ?
FOObaz /13245
TIME-OF-DAY /,
A1B2 LPT:
SAILON 28.7 CHAPTER 3 3-2
Representation:
An identifier is internally represented as a dotted pair of
the following form:
←←←←←←←←←←←
identifier -> | -1 | |-> property list
|←←←←|←←←←|
which is called an atom header.
Thus CDR of an identifier gives the property list of the
identifier, but CAR of an identifier gives the pointer 777777, which
if used as an address will cause an illegal memory reference, and an
error message. An identifier is referred to in symbolic computation
by the address of its atom header.
3.1 Property Lists
The property list of an identifier is a list of pairs:
(property name, property value) associated with that identifier. The
normal kinds of properties which are found in property lists are
print names, values, and function definitions corresponding to
identifiers.
3.1.1 Print Names
Every identifier has a print name (PNAME) on its property
list. The print name of an identifier is a list of full words, each
containing five ASCII characters.
Example: The identifier TIME-OF-DAY would be initially represented
as follows:
←←←←←←←←←← ←←←←←←←←← ←←←←←←←←←
atom -> | -1 | |-> | | |-> | |NIL|
header |←←←←|←←←| |←←←|←←←| |←←←|←←←|
| |
←←←←←←←←← ←←←←←←←←← ←←←←←←←←←
atom | | |-> | | |-> | |NIL|
"PNAME" |←←←|←←←| |←←←|←←←| |←←←|←←←|
| | |
←←←←←←←←← ←←←←←←←←← ←←←←←←←←←
| TIME- | | OF-DA | | Y@@@@ |
|←←←←←←←| |←←←←←←←| |←←←←←←←|
where @ means null or ASCII 0.
SAILON 28.7 CHAPTER 3 3-3
3.1.2 Special Cells
When a value is assigned an identifier, the property name
VALUE is put on the identifier's property list with property value
being a pointer to a special cell. The CDR of the special cell
(sometimes called VALUE cell) holds the value of the identifier, and
the address of a special cell remains constant for that identifier
unless REMPROPed (11.2), to enable compiled functions to directly
reference the values of special variables. Global variables and all
variables bound in interpreted functions store their values in
special cells.
Example: The atom T has the following form:
atom header property list
←←←←←←←←← ←←←←←←←←←← ←←←←←←←←← ←←←←←←←←←← ←←←←←←←←←
| -1| |->|VALUE| |->| | |->|PNAME| |->| |NIL|
|←←←|←←←| |←←←←←|←←| |←←←|←←←| |←←←←←|←←| |←←←|←←←|
↑ | |
| special ←←←←←←←←← ←←←←←←←←←
| cell |NIL| T | print | |NIL|
| |←←←|←←←| name |←←←|←←←|
|←←←←←←←←←←←←←←←←←←←←←←←←←←|
|
←←←←←←←←←
| T@@@@ |
|←←←←←←←|
3.2 The OBLIST
In order that occurrences of identifiers with the same print
names have the same internal address (and hence value), a special
list which is the VALUE of a global variable called OBLIST is used to
remember all identifiers which READ and some other functions have
seen. For the sake of searching efficiency, this list has two
levels; the first level contains sequentially stored "buckets" which
are "hashed" into as a function of the print name of the identifier.
Each bucket is a list of all distinct identifiers which have hashed
into that bucket. Thus, (CAR OBLIST) is the first bucket, and (CAAR
OBLIST) is the first identifier of the first bucket.
3.3 Strings
Syntax:
string::= "<any sequence of characters not containing ">"
SAILON 28.7 CHAPTER 3 3-4
Semantics:
A string is an arbitrary sequence of characters surrounded by
double quotes and not containing double quotes. Strings are
represented identically to identifiers except that strings are not
automatically INTERNed on the OBLIST. The double quotes surrounding
strings actually become part of the PRINT NAME of the string unlike
slashes in slashified identifiers.
Examples:
"I AM A STRING"
"1,3-X 5"
SAILON 28.7 CHAPTER 4 4-1
CHAPTER 4
NUMBERS
There are two syntactic types of numbers: integer and real.
<number> ::= <integer> | <real>
4.1 Integers
Syntax:
<integer> ::= {<sign>} <digits> {.}
<digits> ::= <digit> {<digits>}
<sign> ::= +|-
Semantics:
The global variable IBASE specifies the input radix for
integers which are not followed by "." Integers followed by "." are
decimal integers. IBASE is initially = 8. Similarly, the global
variable BASE controls output radix for integers. If BASE = 10 then
integers will print with a following ".", unless the global variable
*NOPOINT = T.
Examples with IBASE = 8
input meaning
-13 = -11. = -11 base 10
1000 = 512. = +512 base 10
19 = 17. = +17 base 10
Representation:
There are three representations for integers depending on the
numerical magnitude of the integer: INUM, FIXNUM, and BIGNUM. Their
ranges are as follows:
INUM |n| < K K is usually 2↑16
FIXNUM K <= |n| < 2↑35
BIGNUM 2↑35 <= |n|
Representation of INUMs:
INUMs are small integers represented by pointers outside of
the normal LISP addressing space. INUMs are addresses in the range
2↑18-2K to 2↑18-1. The INUM representation for zero is @ = 2↑18-K-1.
SAILON 28.7 CHAPTER 4 4-2
Examples INUM Representation
-(K-1) @ - (K-1)
-1 @ - 1
0 @ = 2↑18-K-1
1 @ + 1
K-1 @ + K-1
Representation of FIXNUMs:
FIXNUMs are represented by list structure of the following form:
Atom header
←←←←←←←← ←←←←←←←←←←←← ←←←←←←←←←
| -1| |-> |FIXNUM| |->| value |
|←←←|←←| |←←←←←←|←←←| |←←←←←←←|
where value is the 2's complement representation of the fixed point
number.
Examples:
←←←←←←←← ←←←←←←←←←←←← ←←←←←←←←←←←←←←
+100000000 | -1| |-> |FIXNUM| |->|000100000000|
|←←←|←←| |←←←←←←|←←←| |←←←←←←←←←←←←|
←←←←←←←← ←←←←←←←←←←←← ←←←←←←←←←←←←←←
-1400000032 | -1| |-> |FIXNUM| |->|776377777746|
|←←←|←←| |←←←←←←|←←←| |←←←←←←←←←←←←|
Representation of BIGNUMs (*** Not supported in UCI LISP):
BIGNUMs are represented by list structure of the following forms:
←←←←←←←← ←←←←←←←←←←← ←←←←←←←←← ←←←←←←←←←
Positive BIGNUMs ->| -1| |-> |POSNUM| |->| | |->| |NIL|
|←←←|←←| |←←←←←←|←←←| |←←←|←←←| |←←←|←←←|
| |
←←←←←←←←← ←←←←←←←←←
| N0 | | Nn |
|←←←←←←←| |←←←←←←←|
←←←←←←←← ←←←←←←←←←←←← ←←←←←←←←← ←←←←←←←←←
Negative BIGNUMs ->| -1| |-> |NEGNUM| |->| | |->| |NIL|
|←←←|←←| |←←←←←←|←←←| |←←←|←←←| |←←←|←←←|
| |
←←←←←←←←← ←←←←←←←←←
| N0 | | Nn |
|←←←←←←←| |←←←←←←←|
SAILON 28.7 CHAPTER 4 4-3
where N|i are positive 36 bit integers ordered from least to most
significant. The value of a BIGNUM is
sign * (N|0 + 2↑35 N, + 2↑35*2 N|2 + ... + 2↑35n N|n)
Note: BIGNUMs are not normally a part of the interpreter. Appendix H
describes the procedures for loading the BIGNUM package.
4.2 Reals
Syntax:
<real> ::= {<sign>} <digits> {.} <exponent>
::= {<sign>} {<digits>} . <digits> {<exponent>}
<exponent> ::= E {<sign>} <digits>
Examples:
meaning
3.14159 +3.14159
+1E-3 +0.001
-196.37E4 -1963700.0
0.3 +0.3
-0.3E+1 -3.0
Restrictions:
The radix for real numbers is always decimal. A real number x
must be in the (approximate) range:
10↑-38 < |x| < 10↑+38 or x = 0
A real number has approximately eight significant digits of accuracy.
Representation:
atom header
←←←←←←←←←← ←←←←←←←←←←←←←←← ←←←←←←←←←
| -1 | | -> |FLONUM| | -> | value |
|←←←←|←←←| |←←←←←←|←←←←←←| |←←←←←←←|
where value is in PDP-6/10 2's complement floating point
representation.
SAILON 28.7 CHAPTER 5 5-1
CHAPTER 5
S-EXPRESSIONS
Syntax:
<atom> ::= <identifier> | <string> | <number>
<S-expression> ::= <atom>
::= (<S-expression list>{.<S-expression>})
::= ( ) = NIL
<S-expression list> ::= <S-expression>
::= <S-expression> <S-expression list>
Representation:
S-expression representation
←←←←←←←←←
(A . (B . C)) -> | A | |
|←←←|←←←|
|
←←←←←←←←←
| B | C |
|←←←|←←←|
←←←←←←←←← ←←←←←←←←← ←←←←←←←←←
((A . B) (C . D) E) -> | | |-> | | |-> | E |NIL|
|←←←|←←←| |←←←|←←←| |←←←|←←←|
| |
←←←←←←←←← ←←←←←←←←←
| A | B | | C | D |
|←←←|←←←| |←←←|←←←|
←←←←←←←←← ←←←←←←←←←
(A B . C) -> | A | |-> | B | C |
|←←←|←←←| |←←←|←←←|
Exceptions:
The identifier NIL is the identifier which represents the
empty list, i.e., ().
SAILON 28.7 CHAPTER 6 6-1
CHAPTER 6
LAMBDA EXPRESSIONS
LAMBDA expressions provide the means of constructing
computational procedures (often called functions, subroutines, or
procedures) which compute answers when values are assigned to their
parameters. A LAMBDA expression can be bound to an identifier so
that any reference to that identifier in functional context refers to
the LAMBDA expression. In LISP 1.6 there are several types of
function definition which determine how arguments are bound to the
LAMBDA expression. The following is a LAMBDA expression:
! (LAMBDA "ARGUMENT-LIST" "BODY")
LAMBDA defines a function by specifying an ARGUMENT-LIST,
which is a list of identifiers (except for LEXPRs, see 6.3) and a
BODY, which is an S-expression. LAMBDA expressions may have no more
than five arguments if they are to be compiled.
Examples: (LAMBDA NIL 1)
This LAMBDA expression of no arguments always
evaluates to one.
(LAMBDA (X) (TIMES X X))
This LAMBDA expression computes the square of
its argument, if x is a number. Otherwise an error
will result.
# (LABEL "ID" "LAMBDA-EXPR")
LABEL creates a temporary name ID for its LAMBDA expression.
This makes it possible to construct recursive functions with
temporary names.
Example:
(DE REVERSE (L)
((LABEL REVEVSE1
(LAMBDA (L M)
(COND ((ATOM L) M)
(T (REVERSE1 (CDR L) (CONS (CAR L) M))))))
L NIL))
LAMBDA expressions are evaluated by "binding" actual
arguments to dummy variables of the LAMBDA expression, (see Chapter
7) then evaluating the body inside the LAMBDA expression with the
current dummy variable bindings. However, actual arguments to LAMBDA
expressions are handled in a variety of ways. Normally, there is a
one-to-one correspondence between dummy variables and actual
arguments, and the actual arguments are evaluated before they are
SAILON 28.7 CHAPTER 6 6-2
bound. However, there are three special forms of function definition
which differ in their handling of actual arguments.
! 6.1 EXPRs and SUBRs
An EXPR is an identifier which has a LAMBDA expression on its
property list with property name EXPR. EXPRs are evaluated by
binding the values of the actual arguments to their corresponding
dummy variables. DE (see 11.1) is useful for defining EXPRs. The
compiled form of an EXPR is a SUBR.
Examples:
(DE SQUARE (X) (TIMES X X))
(DE *MAX (X Y) (COND ((GREATERP X Y) X) (T Y)))
6.2 FEXPRs and FSUBRs
A FEXPR is an identifier which has a LAMBDA expression of one
dummy variable on its property list with property name FEXPR. FEXPRs
are evaluated by binding the actual argument list to the dummy
variable without evaluating any arguments. DF (see 11.1) is useful
for defining FEXPRs. The compiled form of an FEXPR is an FSUBR.
Examples:
(DF LISTQ (L) L)
(LISTQ A (B) C) = (A (B) C)
(LISTQ) = NIL
(DF DEFINE (L)
(MAPC (FUNCTION (LAMBDA (X) (PUTPROP (CAR X)
(CADR X)
(QUOTE EXPR))))
L))
(DEFINE (LEQ (LAMBDA (X Y) (OR (LESSP X Y)
(EQUAL X Y))))
(GEQ (LAMBDA (X Y) (OR (GREATERP X Y)
(EQUAL X Y)))))
# 6.3 LEXPRs and LSUBRs
An LEXPR is an EXPR whose LAMBDA expression has an atomic
argument "list" of the form:
(LAMBDA "ID" "FORM")
LEXPRs may take an arbitrary number of actual arguments which are
evaluated and referred to by the special function ARG. ID is bound
to the number of arguments which are passed. The compiled form of an
LEXPR is an LSUBR.
SAILON 28.7 CHAPTER 6 6-3
(ARG N)
ARG returns the value of the Nth argument to an LEXPR.
Example:
(DE MAX N
(PROG (M)
(SETQ M (ARG N))
L (SETQ N (SUB1 N))
(COND ((ZEROP N) (RETURN M))
((GREATERP (ARG N) M) (SETQ M (ARG N))))
(GO L)))
(MAX 1 1.2 4 3 -50) = 4
(SETARG N V)
SETARG sets the value of the Nth argument to V and returns V.
6.4 MACROs
A MACRO is an identifier which has a LAMBDA expression of one
dummy variable on its property list with property name MACRO. MACROs
are evaluated by binding the list containing the macro name and the
actual argument list to the dummy variable. The body in the LAMBDA
expression is evaluated and should result in another "expanded" form.
In the interpreter, the expanded form is evaluated. In the compiler,
the expanded form is compiled. DM (see 11.1) is useful for defining
MACROs.
Examples:
1) We could define CONS of an arbitrary number of arguments by:
(DM CONSCONS (L)
(COND ((NULL (CDDR L)) (CADR L))
(T (LIST (QUOTE CONS)
(CADR L)
(CONS (QUOTE CONSCONS) (CDDR L))))))
(CONSCONS A B C) would call CONSCONS with L = (CONSCONS A B
C). CONSCONS then forms the list (CONS A (CONSCONS B C)). Evaluating
this will again call CONSCONS with L = (CONSCONS C). CONSCONS will
finally return C.
The effect of (CONSCONS A B C) is then (CONS A (CONS B C)).
2) We could define a function EXPAND which is more generally useful
for MACRO expansion:
(DE EXPAND (L FN)
(COND ((NULL (CDR L)) (CAR L))
(T (LIST FN (CAR L) (EXPAND (CDR L) FN))))))
SAILON 28.7 CHAPTER 6 6-4
Then we could define CONSCONS:
(DM CONSCONS (L) (EXPAND (CDR L) (QUOTE CONS)))
It should be noted that MACROs are more general than FEXPRs
and LEXPRs. In fact the previous definitions can be replaced by the
following MACROs:
(DM LISTQ (L) (LIST (QUOTE QUOTE) (CDR L))))
(DM MAX (L) (EXPAND (CDR L) (QUOTE *MAX)))
(MAX A B C D) would expand to:
(*MAX A (*MAX B (*MAX C D)))
3) (*EXPAND L FN)
(*EXPAND1 L FN)
*EXPAND and *EXPAND1 are MACRO expanding functions used by PLUS,
TIMES, etc. They are equivalent to:
(DE *EXPAND (L FN) (*EXPAND1 (REVERSE (CDR L)) FN))
(DE *EXPAND1 (L FN)
(COND ((NULL (CDR L)) (CAR L))
(T (LIST FN (*EXPAND1 (CDR L) FN) (CAR L)))))
Example:
With PLUS defined as
(DM PLUS (L) (*EXPAND L(QUOTE *PLUS)))
(PLUS A B C D) expands to:
(*PLUS (*PLUS (*PLUS A B) C) D)
SAILON 28.7 CHAPTER 7 7-1
CHAPTER 7
EVALUATION OF S-EXPRESSIONS
This chapter describes the heart of the LISP interpreter, the
mechanism for evaluating S-expressions.
! (*EVAL E)
(EVAL E)
*EVAL and EVAL (see 7.2) evaluate the value of the
S-expression E.
Examples:
(EVAL (LIST (QUOTE ADD1) 3)) = 4
The top level of LISP is:
(PROG NIL
L (PRINT (EVAL (READ))) (TERPRI) (GO L))
! (APPLY FN ARGS)
APPLY binds each S-expression in the value of ARGS to the
corresponding argument of the function FN, and returns the value of
FN. See 7.2.
Example:
(APPLY (FUNCTION APPEND) (QUOTE ((A B) (C D)))) = (A B C D)
! (QUOTE "E")
QUOTE returns the S-expression E without evaluating it.
(FUNCTION "FN")
FUNCTION is the same as QUOTE in the interpreter. In the
compiler, FUNCTION causes the S-expression FN to be compiled, but
QUOTE generates an S-expression constant. See *FUNCTION in 7.2 for
the special FUNARG feature.
The following function definitions lack some details but
explain the essence of EVAL and APPLY. The A-LIST feature of these
functions is not shown, but will be explained in 7.2.
(DE EVAL (X)
(PROG (Y)
(RETURN
(COND ((NUMBERP X) X)
((ATOM X) (COND ((SETQ Y (GET X (QUOTE VALUE)))
(CDR Y))
(T (ERROR (QUOTE (UNBOUND VARIABLE))))))
SAILON 28.7 CHAPTER 7 7-2
((ATOM (CAR X))
(COND ((SETQ Y (GETL (CAR X) (QUOTE (EXPR FEXPR MACRO))))
(COND ((EQ (CAR Y) (QUOTE EXPR))
(APPLY (CADR Y)
(MAPCAR (FUNCTION EVAL) (CDR X))))
((EQ (CAR Y) (QUOTE FEXPR))
(APPLY (CADR Y) (LIST (CDR X))))
(T (EVAL (APPLY (CADR Y) (LIST X))))))
((SETQ Y (GET (CAR X) (QUOTE VALUE)))
(EVAL (CONS (CDR Y) (CDR X))))
(T (ERROR (QUOTE (UNDEFINED FUNCTION))))))
(T (APPLY (CAR X) (MAPCAR (FUNCTION EVAL) (CDR X))))))))
(DE APPLY (FN ARGS)
(COND ((ATOM FN)
(COND ((GET FN (QUOTE EXPR))
(APPLY (GET FN (QUOTE EXPR)) ARGS))
(T (APPLY (EVAL FN) ARGS))))
((EQ (CAR FN) (QUOTE LAMBDA))
(PROG (Z)
(BIND (CADR FN) ARGS)
(SETQ Z (EVAL (CADDR FN)))
(UNBIND (CADR FN))
(RETURN Z)))
(T (APPLY (EVAL FN) ARGS))))
The functions BIND and UNBIND implement variable bindings as
described in the next section.
* 7.1 Variable Bindings
This section attempts to explain the different types of
variable bindings and the difference between interpreter and compiler
bindings.
* 7.1.1 Bound and Free Occurrences
An occurrence of a variable is a "bound occurrence" if the
variable is a variable in any LAMBDA or PROG containing the
occurrence so long as the occurrence is not contained in a FUNCTIONAL
argument which is contained in the defining LAMBDA or PROG. The
defining LAMBDA or PROG is the innermost LAMBDA or PROG which
contains the variable in its parameter list.
Examples:
(LAMBDA (X) (TIMES X Y))
X has a bound occurrence.
Y has a free occurrence.
(LAMBDA (Y Z) (MAPCAR (FUNCTION (LAMBDA (X) (CONS X Y))) Z))
X and Z have only bound occurrences.
Y is bound by the outer LAMBDA and free in the inner.
SAILON 28.7 CHAPTER 7 7-3
* 7.1.2 Scope of Bindings
A variable bound in a LAMBDA or PROG is defined during the
dynamic execution of the LAMBDA or PROG. Free occurrences of
variables are defined if and only if either the variable is globally
defined or the variable is bound in any LAMBDA or PROG which
dynamically contains the free occurrence. A variable is globally
defined if and only if it has a value at the top level of LISP.
Variables can be globally defined by SETQ at the top level.
* 7.1.3 Special Variables
In compiled functions, any variable which is bound in a
LAMBDA or PROG and has a free occurrence elsewhere must be declared
SPECIAL (APPENDIX E).
Example: (*** Not necessary for MAP fns in UCI LISP.)
(LAMBDA (A B)
(MAPCAR (FUNCTION (LAMBDA (X) (CONS A X))) B))
The variable A which has a free occurrence must be declared
SPECIAL if the outer LAMBDA expression is to be compiled.
* 7.1.4 Binding Mechanisms
All variables in interpreted functions, and SPECIAL variables
in compiled functions store their values in SPECIAL (or VALUE) cells.
These variables are bound at the entry to a LAMBDA or PROG by saving
their previous values on the SPECIAL pushdown list and storing their
new values in the SPECIAL cells. All references to these variables
are directly to their SPECIAL cells. When the LAMBDA or PROG is
exited, the old values are restored from the SPECIAL pushdown list.
In compiled functions, all variables not declared SPECIAL are
stored on the REGULAR pushdown list, and the SPECIAL cells (if they
exist) are not referenced.
# 7.2 The A-LIST and FUNARG Features
The A-LIST which is used in some LISP systems to implement
recursive variable bindings does not exist here, but its effects are
simulated through a special A-LIST feature. The functions EVAL and
APPLY allow an extra last argument to be passed which is either a
list of paired identifiers and values (like an A-LIST) or a "binding
context pointer".
In the case of an A-LIST second argument, EVAL and APPLY will
bind the special cells of the variables in the A-LIST to their
specified values, saving their previous bindings on the special
pushdown list. When EVAL and APPLY return, the variable bindings are
restored to their previous values.
SAILON 28.7 CHAPTER 7 7-4
A "binding context pointer" (BCP) is a pointer into the
SPECIAL PUSHDOWN LIST designating a level in recursive variable
binding. When EVAL and APPLY receive a BCP as their second argument,
all SPECIAL (VALUE) CELLS are restored to the values they had at the
time the BCP was generated. This then causes EVAL and APPLY to
reference these variables in the binding context which existed at the
time of BCP generation. This feature primarily is useful to prevent
variable name conflicts when using EVAL, APPLY, and functional
arguments. As with the A-LIST, when EVAL and APPLY exit, the
previous bindings are restored.
There are two ways to generate a BCP:
If an FEXPR is defined with two arguments, then the second
argument will be bound to the SPECIAL PUSHDOWN LIST level at the time
the FEXPR is called.
The second way to generate a BCP is with *FUNCTION.
(*FUNCTION "FN")
*FUNCTION returns a list of the following form:
(FUNARG FN . <BCP>)
where BCP is the SPECIAL PUSHDOWN LIST level at the time *FUNCTION is
called. Whenever such a functional form is used in functional
context, all SPECIAL bindings are restored to the values they had at
the time *FUNCTION was evaluated. When the functional argument has
been APPLYed, the previous bindings are restored as with the A-LIST.
(*** See also the powerful new evaluation context stack
manipulation functions of UCI LISP.)
The use of FUNARGS is discussed further by Robert Saunders[3].
SAILON 28.7 CHAPTER 8 8-1
CHAPTER 8
CONDITIONAL EXPRESSIONS
A conditional expression has the following form:
! (COND (e[1,1] e[1,2] ... e[1,n1])
(e[2,1] e[2,2] ... e[2,n2])
...
(e[m,1] e[m,2] ... e[m,nm]))
where the e[i,j]s are any S-expressions.
The e[i,1]s are considered to be predicates, i.e., evaluate
to a truth value. The e[i,1]s are evaluated starting with e[1,1],
e[2,1], etc., until the first e[k,1] is found whose value is not NIL.
Then the corresponding e[k,2] e[k,3] ... e[k,nk] are evaluated
respectively and the value of e[k,nk] is returned as the value of
COND. It is permissible for nk =1, in which case the value of e[k,1]
is the value of COND. If all e[i,1] evaluate to NIL, then NIL is the
value of COND.
Examples:
(DE NOT (X) (COND (X NIL) (T)))
(DE AND (X Y) (COND (X (COND (Y T)))))
(DE OR (X Y) (COND (X T) (Y T)))
(DE IMPLIES (X Y) (COND (X (COND (Y T))) (T)))
SAILON 28.7 CHAPTER 9 9-1
CHAPTER 9
PREDICATES
Predicates test S-expressions for particular values, forms,
or ranges of values. All predicates described in this chapter return
either NIL or T corresponding to the truth values false and true,
unless otherwise noted. Some predicates cause error messages or
undefined results when applied to S-expressions of the wrong type,
such as (MINUSP (QUOTE FOO)).
! (ATOM X)
The value of ATOM is T if X is either an identifier or a
number; NIL otherwise.
Examples: (ATOM T) = T
(ATOM 1.23) = T
(ATOM (QUOTE (X Y Z))) = NIL
(ATOM (CDR (QUOTE (X))) = T
! (EQ X Y)
The value of EQ is T if X and Y are the same pointer, i.e.,
the same internal address. Identifiers on the OBLIST have unique
addresses and therefore EQ will be T if X and Y are the same
identifier. EQ will also return T for equivalent INUMs, since they
are represented as addresses. However, EQ will not compare equivalent
numbers of any other kind. For non-atomic S-expressions, EQ is T if X
and Y are the same pointer.
Examples: (EQ T T) = T
(EQ T NIL) = NIL
(EQ (QUOTE A) (QUOTE B)) = NIL
(EQ 1 1.0) = NIL
(EQ 1 1) = T
(EQ 1.0 1.0) = NIL
(EQUAL X Y)
The value of EQUAL is T if X and Y are identical
S-expressions. EQUAL can also test for equality of numbers of mixed
types. EQUAL is equivalent to:
(LAMBDA(X Y) (COND ((EQ X Y) T)
((AND (NUMBERP X) (NUMBERP Y))
(ZEROP (*DIF X Y)))
((OR (ATOM X)(ATOM Y)) NIL)
((EQUAL (CAR X) (CAR Y))
(EQUAL (CDR X) (CDR Y)))))
SAILON 28.7 CHAPTER 9 9-2
Examples: (EQUAL T T) = T
(EQUAL 1 1) = T
(EQUAL 1 1.0) = T
(EQUAL (QUOTE (A B)) (QUOTE (A B))) = T
(EQUAL (QUOTE (T)) T) = NIL
! 9.1 S-Expression Predicates
(NULL L) = T if and only if L is NIL.
(MEMBER L1 L2) = T if and only if L1 is EQUAL to a top level element
of L2. (*** Returns tail of L2 in UCI LISP.)
MEMBER is equivalent to:
(LAMBDA(L1 l2) (COND ((NULL L2) NIL)
((EQUAL L1 (CAR L2))T)
(T (MEMBER L1 (CDR L2)))))
Examples: (MEMBER (QUOTE (C D)) (QUOTE ((A B)(C D)E))) = T
(MEMBER (QUOTE C)(QUOTE (C)))) = NIL
(MEMQ L1 L2) = T iff L1 is EQ to a top level element of L2.
(*** Returns tail of L2 in UCI LISP.)
MEMQ is equivalent to:
(LAMBDA(L1 L2)(COND ((NULL L2) NIL)
((EQ L1 (CAR L2)) T)
(T (MEMQ L1 (CDR L2)))))
Examples: (MEMQ (QUOTE (C D))(QUOTE ((A B)(C D) E))) = NIL
(MEMQ (QUOTE A) (QUOTE (Q A B))) = T
! 9.2 Numerical Predicates
(NUMBERP X) = T if X is a number of any type
= Nil otherwise
(ZEROP X) = T if X is zero of any numerical type
= error if X is a non-numerical quantity
= NIL otherwise
(MINUSP X) = T if X is a negative number of any type
= error if X is a non-numerical quantity
= NIL otherwise
(*GREAT X Y) = T if X and Y are numbers of any type and X > Y.
= error if either X or Y is not a number
= NIL otherwise
(*LESS X Y) = (*GREAT Y X)
SAILON 28.7 CHAPTER 9 9-3
(GREATERP X1 X2 ... Xn) = T if (*GREAT X1 X2) and
(*GREAT X2 X3) and
...
(*GREAT Xn-1 Xn)
= error if any Xi is a non-numerical
quantity
= NIL otherwise
(LESSP X1 X2 ... Xn) = (GREATERP Xn Xn-1 ... X1)
Other numerical predicates may be defined as follows:
(DE FLOATP (X) (COND ((EQ X (PLUS X 0))NIL)
((EQ (CADR X) (QUOTE FLONUM)) T)
(T NIL)))
(DE FIXP (X) (NOT (FLOATP X)))
(DE ONEP (X) (ZEROP (DIFFERENCE X 1)))
(DE EVENP (X) (ZEROP (REMAINDER X 2)))
! 9.3 Boolean Predicates
The Boolean predicates perform logical operations on the
truth values NIL and T. A non-NIL value is considered equal to T.
(NOT X) = T if X is NIL
= NIL otherwise
(AND X1 X2 ... Xn) = T if all Xi are non-NIL
(*** Returns Xn in UCI LISP.)
= NIL otherwise
Note: (AND) = T. AND evaluates its arguments from left to right
until either NIL is found in which case the remaining
arguments are not evaluated, or until the last argument
is evaluated.
(OR X1 X2 ... Xn) = T if any Xi is non-NIL
(*** Returns Xi in UCI LISP.)
= NIL otherwise
Note: (OR) = NIL. OR evaluates its arguments from left to right
until either non-NIL is found in which case the remaining
arguments are not evaluated, or until the last argument is
evaluated.
SAILON 28.7 CHAPTER 10 10-1
CHAPTER 10
FUNCTIONS ON S-EXPRESSIONS
This chapter describes functions for building, fragmenting,
modifying, transforming, mapping, and searching S-expressions, as
well as some non-standard functions on S-expressions.
! 10.1 S-Expression Building Functions
(CONS X Y)
The value of CONS of two S-expressions is the dotted pair of
those S-expressions.
Example: (CONS (QUOTE A) (QUOTE B)) = (A.B)
Note: See Appendix D for information on functions associated with
CONSing, such as SPEAK, GCGAG, and GC.
(XCONS X Y) = (CONS Y X)
(NCONS X) = (CONS X NIL)
(LIST X1 ... Xn) = (CONS X1 (CONS X2 ...(CONS Xn NIL)...))
List evaluates all of its arguments and returns a list of
their values.
Examples: (LIST) = NIL
(LIST (QUOTE A)) = A
(LIST (QUOTE A) (QUOTE B)) = (A B)
(*APPEND X Y)
(DE *APPEND (X Y)
(COND ((NULL X) Y)
(T (CONS (CAR X) (*APPEND (CDR X) Y)))))
(APPEND X1 X2 ...Xn) = (*APPEND X1 (*APPEND X2 ...(*APPEND Xn NIL)...))
Example: (APPEND) = NIL
(APPEND @(A B) @(C D) @(E)) = (A B C D E)
! 10.2 S-Expression Fragmenting Functions
(CAR L)
The CAR of a non-atomic S-expression is the first element of
that dotted pair. CAR of an atom is undefined and will usually cause
an illegal memory reference.
SAILON 28.7 CHAPTER 10 10-2
(CDR L)
The CDR of a non-atomic S-expression is the second (and last)
element of that dotted pair. The CDR of an identifier is its
property list. The CDR of an INUM causes an illegal memory
reference. The CDR of any other number is the list structure
representation of that number.
Examples: (CAR (QUOTE (A B C))) = A
(CAR (QUOTE A)) is illegal
(CDR (QUOTE (A B C))) = (B C)
(CDR (QUOTE A)) is the property list of A
(CDR (QUOTE (A))) = NIL
CAAR, CADR,..., CDDDDR
All of the composite CAR-CDR functions with up to four A's
and D's are available.
Examples: (CADR X) = (CAR (CDR X))
(CAADDR X) = (CAR (CAR (CDR (CDR X))))
(LAST L)
LAST returns the last part of a list according to the
following definition:
(DE LAST (L)
(COND ((ATOM (CDR L)) L)
(T (LAST (CDR L)))))
Examples: (LAST (QUOTE (A B C))) = (C) = (C.NIL)
(LAST (QUOTE (A B . C))) = (B.C)
* 10.3 S-Expression Modifying Functions
The following functions for manipulating S-expressions differ
from all others in that they actually modify existing list structure
rather than constructing new list structure. These functions should
be used with caution since it is easy to create structures which will
confuse or destroy the interpreter.
(RPLACA X Y)
Replaces the CAR of X by Y. The value of RPLACA is the modified
S-expression X.
Example: (RPLACA (QUOTE (A B C)) (QUOTE (C D))) = ((C D) B C)
SAILON 28.7 CHAPTER 10 10-3
Representation:
←←←←←←←←← ←←←←←←←←← ←←←←←←←←←
X -> | A | |-> | B | |-> | C |NIL|
BEFORE |←←←|←←←| |←←←|←←←| |←←←|←←←|
←←←←←←←←← ←←←←←←←←←
Y -> | C | |-> | D |NIL|
|←←←|←←←| |←←←|←←←|
←←←←←←←←← ←←←←←←←←← ←←←←←←←←←
X -> | | |-> | B | |-> | C |NIL|
AFTER |←←←|←←←| |←←←|←←←| |←←←|←←←|
|
|
←←←←←←←←← ←←←←←←←←←
Y -> | C | |-> | D |NIL|
|←←←|←←←| |←←←|←←←|
(RPLACD X Y)
RPLACD replaces the CDR of X by Y. The value of RPLACD is
the modified S-expression X.
(NCONC X1 X2 ... Xn)
NCONC is similar in effect to APPEND, but NCONC does not copy
list structures. NCONC modifies list structures by replacing the
last element of X1 by a pointer to X2, the last element of X2 by a
pointer to X3, etc. The value of NCONC is the modified list X1,
which is the concatenation of X1, X2, ..., Xn.
Examples: (NCONC) = NIL
(NCONC (QUOTE (A B)) (QUOTE (C D))) = (A B C D)
Representation:
←←←←←←←←← ←←←←←←←←←
X1 -> | A | |-> | B |NIL|
BEFORE |←←←|←←←| |←←←|←←←|
←←←←←←←←← ←←←←←←←←←
X2 -> | C | |-> | D |NIL|
|←←←|←←←| |←←←|←←←|
←←←←←←←←← ←←←←←←←←←
X1 -> | A | |-> | B | |
AFTER |←←←|←←←| |←←←|←←←|
|
|---------------|
←←|←←←←←← ←←←←←←←←←
X2 -> | C | |-> | D |NIL|
|←←←|←←←| |←←←|←←←|
SAILON 28.7 CHAPTER 10 10-4
10.4 S-Expression Transforming Functions
The following functions transform S-expressions from one form
to another.
(LENGTH L)
LENGTH returns the number of top-level elements of the list
L. LENGTH is equivalent to:
(DE LENGTH (L)
(COND ((ATOM L) 0)
(T (ADD1 (LENGTH (CDR L))))))
(REVERSE L)
REVERSE returns the reverse of the top level of list L.
REVERSE is equivalent to:
(DE REVERSE (L) (REVERSE1 L NIL))
(DE REVERSE 1 (L M)
(COND ((NULL L) M)
(T (REVERSE1 (CDR L) (CONS (CAR L) M)))))
(SUBST X Y S)
SUBST substitutes S-expression X for all EQUAL occurrences of
S-expression Y in S-expression S. SUBST is equivalent to:
(DE SUBST (X Y S)
(COND ((EQUAL Y S) X)
((ATOM S) S)
(T (CONS (SUBST X Y (CAR S))
(SUBST X Y (CDR S))))))
Note: (SUBST 0 0 X) is useful for creating a copy of the list X.
Example: (SUBST 5 (QUOTE FIVE) (QUOTE (FIVE PLUS FIVE IS TEN)))
= (5 PLUS 5 IS TEN)
10.5 S-Expression Mapping Functions
The following functions perform mappings of lists according
to the functional arguments supplied.
(MAP FN L)
MAP applies the function FN of one argument to list L and to
successive CDRs of L until L is reduced to NIL. The value of MAP is
NIL. MAP is equivalent to:
SAILON 28.7 CHAPTER 10 10-5
(DE MAP (FN L)
(PROG NIL
L1 (COND ((NULL L)(RETURN NIL)))
(FN L)
(SETQ L (CDR L))
(GO L1)))
Example: (MAP (FUNCTION PRINT) (QUOTE (X Y Z))) =
PRINT: (X Y Z)
PRINT: (Y Z)
PRINT: (Z)
PRINT: NIL
(MAPC FN L)
MAPC is identical to MAP except that MAPC applies function FN
to the CAR of the remaining list at each step. MAPC is equivalent to:
(DE MAPC (FN L)
(PROG NIL
L1 (COND ((NULL L)(RETURN NIL)))
(FN (CAR L))
(SETQ L (CDR L))
(GO L1)))
Example: (MAPC (FUNCTION PRINT) (QUOTE (X Y Z))) =
PRINT: X
PRINT: Y
PRINT: Z
PRINT: NIL
(MAPLIST FN L)
MAPLIST applies the function FN of one argument to list L and
to successive CDRs of L until L is reduced to NIL. The value of
MAPLIST is the list of values returned by FN. MAPLIST is equivalent
to:
(DE MAPLIST (FN L)
(COND ((NULL L) NIL)
(T (CONS (FN L) (MAPLIST FN (CDR L))))))
Examples: (MAPLIST (FUNCTION CAR) (QUOTE (A B C D))) = (A B C D)
(MAPLIST (FUNCTION REVERSE) (QUOTE (A B C D))) =
((D C B A) (D C B) (D C) (D))
SAILON 28.7 CHAPTER 10 10-6
(MAPCAR FN L)
MAPCAR is identical to MAPLIST except that MAPCAR applies FN
to the CAR of the remaining list at each step. MAPCAR is equivalent
to:
(DE MAPCAR (FN L)
(COND ((NULL L) NIL)
(T (CONS (FN (CAR L)) (MAPCAR FN (CDR L))))))
Examples: (MAPCAR (FUNCTION NCONS) @(A B C D)) = ((A) (B) (C) (D))
(MAPCAR (FUNCTION ATOM) @((X) Y (Z))) = (NIL T NIL)
10.6 S-Expression Searching Functions
(ASSOC X L)
ASSOC searches the list of dotted pairs L for a pair whose
CAR is EQ to X. If such a pair is found it is returned as the value
of ASSOC, otherwise NIL is returned. ASSOC is equivalent to:
(DE ASSOC (X L)
(COND ((NULL L) NIL)
((EQ X (CAAR L)) (CAR L))
(T (ASSOC X (CDR L)))))
Example: (ASSOC 1 (QUOTE ((1 . ONE) (2 . TWO)))) = (1 . ONE)
(SASSOC X L FN)
SASSOC searches the list of dotted pairs L for a pair whose
CAR is EQ to X. If such a pair is found it is returned as the value
of ASSOC, otherwise the value of FN, a function of no arguments, is
returned.
(DE SASSOC (X L FN)
(COND ((NULL L) (FN))
((EQ X (CAAR L)) (CAR L))
(T (SASSOC X (CDR L) FN))))
Example: (SASSOC 0 (QUOTE ((1 . ONE) (2 . TWO)))
(FUNCTION (LAMBDA NIL (QUOTE LOSE)))) = LOSE
10.7 Character List Transforming Functions
(EXPLODE L)
EXPLODE transforms an S-expression into a list of single
character identifiers identical to the sequence of characters which
would be produced by PRIN1.
Example: (EXPLODE (QUOTE (DX - DY)))
= (/( D X /← - /← D Y /))
SAILON 28.7 CHAPTER 10 10-7
(EXPLODEC L)
Same as EXPLODE, except PRINC is used for unpacking instead
of PRIN1.
(FLATSIZE L) = (LENGTH (EXPLODE L))
(MAKNAM L)
MAKNAM transforms a list of single character identifiers
(actually takes the first character of each identifier) into an
S-expression identical to that which would be produced by READing
those characters. MAKNAM however does not INTERN any of the
identifiers in the S-expression it produces.
Examples: (MAKNAM (QUOTE (A P P L E))) = APPLE
(MAKNAM (QUOTE (//←/)))) = /)
(READLIST L)
READLIST is identical to MAKNAM except that READLIST INTERNs
all identifiers in the S-expression it produces. READLIST is the
logical inverse of EXPLODE, i.e.,
(READLIST (EXPLODE L)) = L
(EXPLODE (READLIST L)) = L
SAILON 28.7 CHAPTER 11 11-1
CHAPTER 11
FUNCTIONS ON IDENTIFIERS
There are three basic types of functions on identifiers:
those which manipulate their property lists, those which create new
identifiers, and those which control their membership in the OBLIST.
NOTE: All functions described in this chapter which expect an
identifier as one (or more) of its arguments will give either
erroneous results, or an error condition if any S-expression other
than an identifier is supplied.
11.1 Property List Functions
(GET I P)
GET is a function which searches the property list of the
identifier I looking for the property name which is EQ to P. If such
a property name is found, the value associated with it is returned as
the value of GET, otherwise NIL is returned. Note that confusion
exists if the property is found, but its value is NIL. GET is
equivalent to:
(DE GET (I P) (COND ((NULL (CDR I)) NIL)
((EQ (CADR I) P) (CADDR I))
(T (GET (CDDR I) P))))
(GETL I L)
GETL is another function which searches property lists. GETL
searches the property list of the identifier I looking for the first
property which is a member (MEMQ) of the list L. GETL returns the
remaining property list, including the property name if any such
property was found, NIL otherwise. GETL is equivalent to:
(DE GETL (I L) (COND ((NULL (CDR I)) NIL)
((MEMQ (CADR I) L) (CDR I))
(T (GETL (CDDR I) L))))
(PUTPROP I V P)
PUTPROP is a function which enters the property name P with
property value V into the property list of identifier I. If the
property name P is already in the property list, the old property
value is replaced by the new one; otherwise the new property name P
and its value V are placed on the beginning of the property list.
PUTPROP returns V.
SAILON 28.7 CHAPTER 11 11-2
(REMPROP I P)
REMPROP removes the property P from the property list of
identifier I. REMPROP returns T if there was such a property, NIL
otherwise.
SET and SETQ are used to change the values of variables which
are bound by either LAMBDA or PROG, or variables which are bound
globally. (See 7.1).
* (SET E V)
SET changes the value of the identifier specified by the
expression E to V and returns to V. Both arguments are evaluated.
Note: In compiled functions, SET can be used only on globally bound
and special variables.
! (SETQ "ID" V)
SETQ changes the value of ID to V and returns V. SETQ
evaluates V, but does not evaluate ID.
(DEFPROP "I" "V" "P") = (PROG2 (PUTPROP @I @V @P) @I)
DEFPROP is the same as PUTPROP except that it does not
evaluate its arguments, and DEFPROP returns I.
Example: (DEFPROP POSP (LAMBDA (X) (GREATERP X 0)) EXPR)
(DE "ID" "ARGS" "BODY")
DE places the form (LAMBDA ARGS BODY) on the property list of
ID under property EXPR. If ID previously had any of the properties
EXPR, FEXPR, SUBR, FSUBR, LSUBR, or MACRO, then DE will return the
list (ID REDEFINED). Otherwise, DE returns ID.
(DF "ID" "ARGS" "BODY")
Same as DE except defines a function with FEXPR property.
(DM "ID" "ARGS" "BODY")
Same as DE except defines a MACRO.
11.2 OBLIST Functions
(INTERN I)
INTERN puts the identifier I in the appropriate bucket of
OBLIST. If the identifier is aready a member of the OBLIST, then
INTERN returns a pointer to the identifier already there. Otherwise,
INTERN returns I.
SAILON 28.7 CHAPTER 11 11-3
Note: INTERN is only necessary when an identifier which was created
by
GENSYM, MAKNAM, or ASCII needs to be uniquely stored.
(REMOB "X1" "X2 ... "Xn")
REMOB removes all of the identifiers X1, X2, ..., Xn from
the OBLIST and returns NIL. None of the Xi's are evaluated.
Example: (REMOB FOO BAZ)
11.3 Identifier Creating Functions
The following functions create new identifiers but do not
INTERN them onto the OBLIST.
(GENSYM)
GENSYM increments the generated symbol counter and returns a
new identifier specified by the counter. The GENSYM counter is
initialized to the identifier G0000. Successive executions of
(GENSYM) will return.
G0001, G0002, G0003, ...
(CSYM "I")
CSYM initializes generated symbol counter to the identifier
I, and returns I. CSYM does not evaluate its argument.
Example: (CSYM ARY00) = ARY00
(GENSYM) = ARY01
(GENSYM) = ARY02
etc.
(ASCII N)
ASCII creates a single character identifier whose ASCII print
name equals N.
Example: (AsCII 101) is an identifier with print name "A".
SAILON 28.7 CHAPTER 12 12-1
CHAPTER 12
FUNCTIONS ON NUMBERS
There are two types of functions which operate on numbers to
create new numbers: arithmetic and logical.
! 12.1 Arithmetic Functions
Unless otherwise noted, the following arithmetic functions
are defined for both integer, real and mixed combinations of
arguments, and evaluate all their arguments. The result is real if
any argument is real, and integer if all arguments are integer. Most
arithmetic functions may cause overflow which produces an error
message.
(MINUS X) = -X
(*PLUS X Y) = X + Y
(PLUS X1 X2 ... Xn) = X1 + X2 + ... + Xn
(*DIF X Y) = X - Y
(DIFFERENCE X1 X2...Xn) = X1 - X2 - ... - Xn
(*TIMES X Y) = X * Y
(TIMES X1 X2 ... Xn) = X1 * X2 * ... * Xn
(*QUO X Y) = X / Y
(QUOTIENT X1 X2 ...Xn) = X1 / X2 / ... / Xn
For integer arguments, *QUO and QUOTIENT give the integer
part of the real quotient of the arguments.
Examples: (*QUO 5 2) = 2
(*QUO -5 2) = -2
(REMAINDER X Y) ... X - (X / Y) * Y
Note: Remainder is not defined for real arguments.
(DIVIDE X Y) = (CONS (QUOTIENT X Y) (REMAINDER X Y))
(GCD X Y) GCD returns the greatest common divisor of the integers X
and Y.
(ADD1 X) = X + 1
(SUB1 X) = X - 1
(ABS X) = | X |
SAILON 28.7 CHAPTER 12 12-2
(FIX X) returns the largest integer not greater than X.
Examples: (FIX 1) = 1
(FIX 1.1) = 1
(FIX -1.1) = -2 not -1
Other arithmetic functions not defined in the LISP interpreter
can be defined as follows:
(FLOAT X) = (*PLUS X 0.0)
(RECIP X) = (QUOTIENT 1 X)
(SIGN X) = (COND ((ZEROP X) 0)
((MINUSP x) -1)
(T 1))
(ROUND X) = (TIMES (SIGN X) (FIX (PLUS (ABS X) 0.5)))
Examples: (ROUND .5) = 1
(ROUND .49) = 0
(ROUND -.49) = 0
(ROUND -35.1) = -35
(MIN X Y) = (COND ((LESSP X Y) X) (Y))
(MAX X Y) = (COND ((LESSP X Y) Y) (X))
Examples: (MINUS 1) = -1
(MINUS -1.2) = 1.2
(PLUS 1 2 3.1 = 6.1
(PLUS 6 3 -2) = 7
(DIFFERENCE 6 3 1) = 2
(TIMES -2 2.0) = -4.0
(QUOTIENT 5 2) = 2
(QUOTIENT 5.0 2) = 2.5
(QUOTIENT -5 2) = 2
(REMAINDER 5 2) = 1
(REMAINDER -5 2) = -1
(REMAINDER 5.0 2) = undefined
(ABS -32.5) = 32.5
(FIX 32.5) = 32.
(FIX -32.5) = -33.
12.2 Logical Functions
The following functions are intended to operate on INUM and
FIXNUM arguments, but their results are not defined for BIGNUM or
FLONUM (real) arguments.
SAILON 28.7 CHAPTER 12 12-3
(BOOLE N X1 X2 ... Xn)
BOOLE causes a 36 bit Boolean operation to be performed on
its arguments. The value of N specifies which of 16 Boolean
operations to perform.
For n = 2, each bit|i in (BOOLE N A B) is defined:
N result N result
← ←
0 0 10 A|i AND B|i
1 A|i AND B|i 11 A|i EQ B|i
← ←
2 A|i AND B|i 12 A|i
←
3 B|i 13 A|i OR B|i
← ←
4 A|i AND B|i 14 B|i
←
5 A|i 15 A|i OR B|i
←
6 A|i NE B|i 16 A|i OR B|i
7 A|i OR B|i 17 1
For n > 2, BOOLE is defined:
(BOOLE N ... (BOOLE N (BOOLE N X1 X2) X3) ... Xn)
(LSH X N)
LSH performs a logical left shift of N places on X. If n is
negative, X will be shifted right. In both cases, vacated bits are
filled with zeros.
Examples with IBASE = 8
(BOOLE 1 76 133) = 32
(BOOLE 1 76 133 70) = 30
(BOOLE 12 13 0) = 777777777764
(BOOLE 7 7 12) = 17
(LSH 15 2) = 64
(LSH 15 -2) = 3
(LSH -1 -2) = 177777777777
SAILON 28.7 CHAPTER 13 13-1
CHAPTER 13
PROGRAMS
The "program feature" allows one to write ALGOL-like
sequences of statements with program variables and labels.
(PROG "VARLIST" "BODY")
PROG is a function which takes as arguments VARLIST, a list
of program variables which are initialized to NIL when the PROG is
entered (see 7.1), and a BODY which is a list of labels (which are
identifiers) and statements which are non-atomic S-expressions. PROG
evaluates its statements in sequence until either a RETURN or GO is
evaluated, or the list of statements is exhausted, in which the value
of PROG is NIL.
(RETURN X)
RETURN causes the PROG containing it to be exited with the
value X.
(GO "ID")
GO causes the sequence of control within a PROG to be
transferred to the next statement following the label ID. In
interpreted PROGs, if ID is non-atomic, it is repeatedly evaluated
until an atomic value is found. However, in compiled PROGs, ID is
evaluated only once. GO cannot transfer into or out of a PROG.
Note: Both RETURN and GO should only occur either at the top level
of a PROG, or in compositions of COND, AND, OR, and NOT which are at
the top level of a PROG.
Example: The function LENGTH may be defined as follows:
(DE LENGTH (L)
(PROG (N)
(SETQ N 0)
L1 (COND ((ATOM L) (RETURN N)))
(SETQ N (ADD1 N))
(SETQ L (CDR L))
(GO L1)))
(PROG2 X1 X2 ... Xn) , n <= 5.
PROG2 evaluates all expressions X1 X2 ... Xn, and returns the
value of X2.
SAILON 28.7 CHAPTER 14 14-1
CHAPTER 14
INPUT/OUTPUT
14.1 File Names
Syntax: <filename - list> ::= <device-name>
::= <filename-list><device-name>
::= <filename-list><filename>
<device - name> ::= <identifier>:
::= (<atom><atom>)
<filename> ::= <identifier>
::= (<identifier> . <identifier>)
Semantics:
A device-name is either an identifier ending with colon (:)
which is the name of some input or output device, or a list
containing a project-programmer number which implicitly specifies the
disk.
A filename is either an identifier which specifies a filename
with a blank extension, or a dotted pair of filename and extension.
In both cases the filename applies to the most recently (to the left)
specified device-name.
14.2 Channel Names
Channel names can optionally be assigned to files selected by
the functions INPUT and OUTPUT. A channel name is any identifier
which is not followed by a colon. If no channel name is specified to
INPUT or OUTPUT then the channel name T is assumed. The channel name
NIL specifies the teletype in the functions INC and OUTC. Up to 14
channels may be active at any time.
14.3 Input
14.3.1 Selection and Control
(INPUT "CHANNEL" . "FILENAME-LIST")
INPUT releases any file previously initialized on the
channel, and initializes for input the first file specified by the
filename-list. INPUT returns the channel if one was specified, T
otherwise. INPUT does not evaluate its arguments.
(INC CHANNEL ACTION)
INC selects the specified channel for input. The channel NIL
selects the teletype. If ACTION = NIL then the previously selected
input file is not released, but only deselected. If ACTION = T then
that file is released, making the previously selected channel
SAILON 28.7 CHAPTER 14 14-2
available.
The input functions in 14.3.3 receive input from the selected
input channel. When a file on the selected channel is exhausted,
then the next file in the filename-list for the channel is
initialized and input, until the filename-list is exhausted. Then
the teletype is automatically selected for input and (ERR (QUOTE
$EOF$)) is called. The use of ERRSET around any functions which
accept input therefore makes it possible to detect end of file. If
no ERRSET is used, control returns to the top level of LISP. INC
evaluates its arguments, and returns the previously selected channel
name.
In order to READ from multiple input sources, separate
channels should be initialized by INPUT, and INC can then select the
appropriate channel to READ from.
Example: The following show a fairly typical sort of manipulation of two
files at once.
(LAMBDA (FILE)
(PROG (CHAN1 CHAN2 EXPR1 EXPR2)
(SETQ CHAN1 (INPUT DSK: FOO))) ;initialize FOO with channel name T
(SETQ CHAN2 (EVAL (LIST @INPUT (GENSYM) @DSK: FILE)))
;this file is given a GENSYM channel name to prevent
with any existing channels
LOOP (INC CHAN1 NIL) ;select first channel
(SETQ EXPR1 (ERRSET (READ))) ;read an expression from FOO
(COND ((EQ EXPR1 (QUOTE $EOF$)) (GO EXIT1))) ;end of first file?
(SETQ EXPR1 (CAR EXPR1)) ;undo effect of ERRSET
(INC CHAN2 NIL) ;open second channel
(SETQ EXPR2 (ERRSET (READ))) ;read an expression
(COND ((EQ EXPR2 (QUOTE $EOF$)) (GO EXIT2)) ;end of this file?
((ATOM EXPR2) (GO ERROR))) ;read error?
(SETQ EXPR2 (CAR EXPR2)) ;undo effect of errset
..........................
process EXPR1 and EXPR2
..........................
(GO LOOP)
ERROR ;error routine
EXIT1 ;exit when first file ends first
EXIT2 ;exit when sencond file ends first
etc.
(DSKIN . "FILENAME-LIST")
In loading a file into a LISP program, it is not normally
necessary to make use of the full generality available in INC and
INPUT. The function DSKIN is supplied for this purpose. It has the
same effect as doing INC and INPUT on its arguments, except that no
channel name is admissible, and no device name is required. The
SAILON 28.7 CHAPTER 14 14-3
channel name will always be unique, and DSK: will be supplied as a
device name, if none is given.
Example:
(DSKIN FOO DTA3: BAR (1,2) (SIMU.MAN))
will READ the files FOO from DSK:, BAR from DTA3: and
SIMU.MAN from the disk area [1,2].
14.3.2 Teletype Input Control
When input is from the teletype, READ is terminated by either
an entire S-expression or by an incomplete S-expression followed by
altmode. Altmode has the effect of typing a space followed by the
appropriate number of right parens to complete the S-expression.
This feature is particularly useful when an unknown number of right
parens are needed or when in (DDTIN NIL) mode.
* (DDTIN X)
DDTIN is a function which selects teletype input mode. With
(DDTIN NIL), and typing to READ, READCH, or TYI, a rubout will delete
the last character typed, and control U (↑U) will delete the entire
last line typed. Input is not seen by LISP until either altmode or
carriage return is typed.
With (DDTIN T) and typing to READ, a rubout will delete the
entire S-expression being read and start reading again.
Note: (DDTIN T) is not recommended when the time-sharing system is
swapping, since the program is reactivated (and hence swapped
into core) after every character typed.
14.3.3 Input Transfer
! (READ)
READ causes the next S-expression to be read from the
selected input device, and returns the internal representation of the
S-expression. READ uses INTERN to guarantee that references to the
same identifier are EQ.
READ will accept any S-expression which conforms to the
following syntax:
SAILON 28.7 CHAPTER 14 14-4
Syntax:
<readable S-expr> ::= <atom>
::= @<readable S-expr>
::= (<readable S-exprlist>
{.<readableS-expr>})
::= [<unbalanced S-expression list>]
::= ( ) = NIL
<readable S-expr list> ::= <readable S-expr>
::= <readable S-expr><readable S-
expression list>
Semantics:
The delimiter "@" designates that the following readable
S-expression is to be quoted.
Examples: @A means (QUOTE A)
@(@A B) means (QUOTE ((QUOTE A) B))
@@A means (QUOTE (QUOTE A)))
The delimiters "[" and "]" operate as "super-parentheses". A
right bracket "]" will close all open left parentheses ")" up to the
matching left bracket "[". If there is no matching left bracket, it
will close the entire S-expression as does altmode. No syntax is
given for unbalanced-S-expression-list, but it is intended to mean an
S-expression-list which is lacking one or more right parentheses.
Example: (COND [(ATOM X) (REVERSE(CDR Y][T(APPEND Y Z])
(COND ((ATOM X) (REVERSE(CDR Y)))(T(APPEND Y Z)))
(READCH)
READCH causes the next character to be read from the selected
input device and returns the corresponding single character
identifier. READCH also uses INTERN.
(TYI)
TYI causes the next character to be read from the selected
input device and returns the ASCII code for that character.
A function TEREAD which ignores all characters until a
line-feed is seen can be defined:
(DE TEREAD NIL
(PROG NIL
L (COND ((EQ (TYI) 12) (RETURN NIL)))
(GO L)))
SAILON 28.7 CHAPTER 14 14-5
14.4 Output
14.4.1 Selection and Control
(OUTPUT "CHANNEL" . "FILENAME-LIST")
OUTPUT initializes for output on the specified channel the
single file specified by the filename-list. OUTPUT does not evaluate
its arguments, and returns the channel name if specified, T
otherwise.
(OUTC CHANNEL ACTION)
OUTC selects the specified channel for output. The channel
NIL selects the teletype. The output functions in 14.4.3 transfer
output to the selected output channel.
If ACTION = NIL, then the previously selected output file is
not closed, but only deselected. If ACTION = T then that file is
closed, i.e., an end of file is written. OUTC evaluates its
arguments and returns the previously selected channel name. At the
top level, ACTION need not be specified.
Examples: (At the top level)
(OUTC (OUTPUT LPT:) T)
(OUTC NIL T)
(OUTPUT FOO DSK: BAZ)
(OUTC (QUOTE FOO) NIL)
(LINELENGTH N)
LINELENGTH is used to examine or change the maximum output
linelength on the selected output channel. If N = NIL then the
current linelength is returned unchanged, otherwise the linelength is
changed to the value of N which is returned and must be an integer.
(CHRCT)
CHRCT returns the number of character positions remaining on
the output line of the selected output channel.
When characters are output, if CHRCT is made negative, an
ASCII 31 followed by a carriage-return and a line-feed are output.
These characters are completely ignored on input. (See Chapter 3).
14.4.2 Output Transfer
! (PRIN1 S)
PRIN1 causes the S-expression S to be printed on the selected
output device with no preceding or following spaces. PRIN1 also
inserts slashes ("/") before any characters in identifiers which
SAILON 28.7 CHAPTER 14 14-6
would be syntactically incorrect otherwise (see Chapter 3). Double
quotes around strings are printed.
(PRINC S)
PRINC is the same as PRIN1 except that no slashes are
inserted and double quotes around strings are not printed.
(TERPRI X)
TERPRI prints a carriage-return and line-feed and returns the
value of X. X may be omitted if the value of TERPRI is not used.
Example: (PRINC (TERPRI X))
is the same as
(PROG2 (TERPRI) (PRINC X))
! (PRINT S)
= (PROG2 (TERPRI)
(PRIN1 S)
(PRINC (QUOTE /←)))
(TYO N)
TYO prints the character whose ASCII value is N, and returns
N.
SAILON 28.7 CHAPTER 15 15-1
CHAPTER 15
ARRAYS
(ARRAY "ID" TYPE B|1 B|2 ... B|n) n <= 5.
ARRAY is a function which declares an array with name ID, and
places an array referencing function on the property list of ID. TYPE
determines the type of an array as follows:
TYPE INITIAL VALUE ARRAY ELEMENT
T NIL LISP S-expressions stored as
pointers; 2 per word.
NIL 0.0 REAL numbers stored one per word in
PDP-6/10 floating point representation.
36. 0 36 bit 2/s complement integers stored
1 per word.
0<n<36. 0 n bit positive integers packed
[36./n] per word.
B|1 B|2 ... B|n are array subscript bounds which should evaluate to
either positive integers S|i, or to dotted pairs of integers (L|i .
U|i) where L|i <= U|i, which specify lower and upper subscript bounds
as follows:
B|i LOWER BOUND UPPER BOUND LENGTH
S|i 0 S|i - 1 S|i
(L|i . U|i) L|i U|i U|i-L|i + 1
The elements of an array are referenced by:
(<array name> i|1 i|2 ... i|n) where L|j <= i|j < U|j.
The ARRAY subscripts i|j must be integers. References to memory
locations outside of the area reserved for the array are prohibited
and will cause an illegal memory reference message. Array elements
are stored in BINARY PROGRAM SPACE.
Examples:
1) To declare a 1 dimensional array CHARS of 7 bit characters and
with subscripts 1 to 50:
(ARRAY CHARS 7 (QUOTE (1 . 50)))
The first element of CHARS is referenced:
SAILON 28.7 CHAPTER 15 15-2
(CHARS 1)
2) To declare a 2-dimensional array A of REAL numbers and with
subscripts 0 <= i < N, 0 <= j < M:
(ARRAY A NIL N M)
3) To declare a 1-dimensional array FOO of S-expressions and with
subscripts -K <= i <= K:
(ARRAY FOO T (CONS (MINUS K) K))
*(EXARRAY "ID" TYPE B|1 B|2 ... B|n) N <= 5.
EXARRAY is identical to ARRAY except that array elements are
stored in the body of a subroutine loaded by the LOADER (see Appendix
H), and exarray elements are not initialized. The array referencing
subroutine is stored in BINARY PROGRAM SPACE as with ARRAY. EXARRAY
searches symbol tables as does GETSYM (see Appendix H).
Note: Both ARRAY and EXARRAY consume BINARY PROGRAM SPACE. If
there is insufficient room there (see Appendix C) the error message
"BINARY PROGRAM SPACE EXCEEDED" will result.
(STORE ("ID" i|1 i|2 ... i|n) value)
STORE changes the value of the specified array element to
value, and returns value.
Note: STORE evaluates its second argument first.
Examples: With the arrays declared previously:
(STORE (FOO 0) (QUOTE (A B)))
(STORE (FOO (BAZ L)) 1)
(STORE (A I J) (A J I))
(STORE (CHARS 1) 17)
15.1 Examine and Deposit
(EXAMINE N)
EXAMINE returns as an integer the contents of memory location
N.
(DEPOSIT N V)
DEPOSIT stores the integer V in memory location N and returns
V.
SAILON 28.7 CHAPTER 16 16-1
CHAPTER 16
OTHER FUNCTIONS
(TIME)
TIME returns the number of milliseconds your job has computed
since you logged into the system.
(ERRSET E "F")
ERRSET evaluates the S-expression E and if no error occurs
during its evaluation, ERRSET returns (LIST E). If an error occurs,
then the error message will be suppressed if and only if F = NIL, and
NIL is returned as the value of ERRSET. If the function ERR is
called during evaluation, then no message is printed and ERRSET
returns the value returned by ERR.
The following example shows the use of ERRSET to keep trying
to initialize the line printer until it is available:
(DE LPTGRAB NIL
(PROG NIL
L (COND ((ATOM (ERRSET (OUTPUT LPT:) NIL))
(WAIT) (GO L)))))
where WAIT is some function (such as the time-sharing sleep UUO)
which causes a delay.
(ERR E)
ERR returns the value of E to the most recent ERRSET, or to
the top level of LISP if there is no ERRSET.
(*RSET X) flag = NIL initially
*RSET sets a special flag in the interpreter to the value of X, and
returns the previous value of the flag. Normally, with (*RSET NIL),
when an error occurs, special variables are restored to their top
level values from the special pushdown list, and the top level
READ-EVAL-PRINT loop is entered.
With (*RSET T), specials are not restored, neither pushdown
list is changed, and the READ-EVAL-PRINT loop is entered. This makes
it possible to examine the variable bindings immediately after an
error message has been printed. (*** In order to exit from such an
error break in UCI LISP type ↑↑ (two up-arrows) followed by a <cr>.)
SAILON 28.7 CHAPTER 16 16-2
(INITFN FN)
INITFN selects the function of no arguments FN as an
initialization function which is evaluated after a LISP error return
to the top level has occurred or whenever a BELL is typed. INITFN
returns the previously selected initialization function.
Initialization functions are useful when it is desirable to
change the top level of LISP. For instance,
(INITFN (FUNCTION EVALQUOTE))
causes the top level to become EVALQUOTE instead of EVAL.
SAILON 28.7 APPENDIX A A-1
APPENDIX A
ALVINE
by John Allen
(*** Obsolete (and unavailable) in UCI LISP. See the structure
editor described in the UCI LISP Manual.)
SAILON 28.7 APPENDIX B B-1
APPENDIX B
ERROR MESSAGES
The LISP interpreter checks for some error conditions and
prints messages accordingly. Many erroneous conditions are not
tested and result in either the wrong error message at some later
time, or no error message at all. In the latter case the system has
screwed you (or itself) without complaining.
The following is an alphabetical listing of error messages,
their cause, and in some cases, their remedy. Some error messages
print two lines, such as:
FOO
UNBOUND VARIABLE - EVAL
These messages are described last in the listing, and are of the
form:
X <message>
BINARY PROGRAM SPACE EXCEEDED
ARRAY, EXARRAY, or LAP has exceeded BINARY PROGRAM SPACE.
ALLOCATE more BPS next time.
CAN'T EXPAND CORE
INPUT, OUTPUT, LOAD, or ED failed to expand core. Your job
is too large.
CAN'T FIND FILE - INPUT
The input file was not found. You probably forgot to give
the file name extension, or a legal name list.
DEVICE NOT AVAILABLE
INPUT or OUTPUT found the specified device unavailable. Some
other job is probably using it.
DIRECTORY FULL
The directory of the output device is full.
SAILON 28.7 APPENDIX B B-2
DOT CONTEXT ERROR
READ does not like dots adjacent to parens or other dots.
FILE IS WRITE-PROTECTED
OUTPUT found that the specified file is write-protected.
FIRST ARGUMENT NON-ATOMIC - PUTPROP
An attempt was made to PUTPROP onto a non-identifier.
GARBAGED OBLIST
Some member of the OBLIST has been garbaged. You are in
trouble.
ILLEGAL DEVICE
INPUT or OUTPUT was attempted to either a non-existent device
or to a device of the wrong type. I.e., INPUT from the
lineprinter.
ILLEGAL OBJECT - READ
READ objects to syntactically incorrect S-expressions.
INPUT ERROR
Bad data was read from the selected device.
MORE THAN ONE S-EXPRESSION - MAKNAM
MAKNAM and READLIST object to a list which constitutes the
characters for more than one S-expression.
NO FREE STG LEFT
All free storage is bound to the OBLIST and protected cells
(such as list ARRAY cells), and bound variables on either the
REGULAR or SPECIAL pushdown list. Unbinding to the top level
will usually release the storage. If you are in a bind for
more free storage, try to REALLOC as described in APPENDIX C.
NO FULL WORDS LEFT
All full words are being used for print names and numbers.
The problem and its solution are similar to FREE STG.
SAILON 28.7 APPENDIX B B-3
NO I/O CHANNELS LEFT
INPUT or OUTPUT failed to find a free I/O channel. There is
a maximum of 14 active I/O channels.
NO INPUT - INC
An attempt was made to select a channel for input with INC
which was not initialized with INPUT.
NO LIST - MAKNAM
MAKNAM and READLIST object to an empty list.
NO OUTPUT - OUTC
An attempt was made to select a channel for output with OUTC
which was not initialized with OUTPUT.
NO PRINT NAME - INTERN
INTERN found a member of the OBLIST which has no print name.
You are in trouble.
OUTPUT ERROR
Data was improperly written on the selected output device.
Possibly a write-locked DECTAPE.
OVERFLOW
Some arithmetic function caused overflow - either fixed or
floating.
PDL OVERFLOW FROM GC - CAN'T CONTINUE
There is not enough regular pushdown list to finish garbage
collection. You lose. Try to REALLOC as described in
APPENDIX C.
READ UNHAPPY - MAKNAM
MAKNAM and READLIST object to a list which is not an entire
S-expression.
REG PUSHDOWN CAPACITY EXCEEDED
SPEC PUSHDOWN CAPACITY EXCEEDED
A pushdown list has overflowed. This is usually caused by
non-termination of recursion. Sometimes you need to ALLOCATE
or REALLOC more pushdown list.
SAILON 28.7 APPENDIX B B-4
TOO FEW ARGUMENTS SUPPLIED - APPLY
TOO MANY ARGUMENTS SUPPLIED - APPLY
APPLY checks all calls on interpreted functions for the
proper number of arguments.
X MADE ILLEGAL MEMORY REFERENCE
The function X referred to an illegal address. Usually
caused by taking the CAR or CDR of an atom or number.
X NON-NUMERIC ARGUMENT
Arithmetic functions require that their arguments be numbers.
X PROGRAM TRAPPED FROM
An illegal instruction was executed in function X.
X UNBOUND VARIABLE - EVAL
EVAL tried to evaluate an identifier and found that it had no
value. You probably forgot to QUOTE some atom to initialize
it.
X UNDEFINED COMPUTED GO TAG IN
A GO in some compiled function had an undefined label.
X UNDEFINED FUNCTION X UNDEFINED FUNCTION - APPLY
The function X is not defined.
X UNDEFINED PROG TAG - GO
A GO in some interpreted function had an undefined label.
SAILON 28.7 APPENDIX C C-1
APPENDIX C
MEMORY ALLOCATION
The LISP 1.6 system has many different areas of memory for
storing data which can independently vary in size. Some LISP
applications demand larger allocations for these areas than others.
To allow users to adjust the sizes of these areas to their own needs,
a memory allocation procedure exists.
C.1 Summary of Storage Allocation Areas
BINARY PROGRAM SPACE Area for compiled functions and arrays.
FREE STORAGE Area for LISP nodes.
FULL WORD SPACE Area for print names and numbers.
BIT TABLES Area for the garbage collector.
REGULAR PUSHDOWN LIST Area for all function calls and non-
special variables in compiled functions.
SPECIAL PUSHDOWN LIST Area for interpreted variables and special
variables.
EXPANDED CORE Area for I/O buffers, ALVINE, LOADER, and
any loaded programs.
TOP OF CORE
←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←
| |
| EXPANDED CORE |
|←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←|
| |
| SPECIAL PUSHDOWN LIST |
|←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←|
| |
Memory map | REGULAR PUSHDOWN LIST |
for the LISP |←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←|
1.6 system | |
| BIT TABLES |
|←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←|
| |
| FULL WORD SPACE |
|←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←|
| |
| FREE STORAGE |
|←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←|
| |
| BINARY PROGRAM SPACE |
|←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←|
| |
| LISP INTERPRETER |
|←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←|
BOTTOM OF CORE
SAILON 28.7 APPENDIX C C-2
C.2 ALLOCATION
(*** See the UCI LISP function REALLOC.)
SAILON 28.7 APPENDIX D D-1
APPENDIX D
GARBAGE COLLECTION
All LISP systems have a function known as the garbage
collector. This function analyzes the entire state of list structure
which is pointed to by either the OBLIST, the regular pushdown list,
the special pushdown list, list arrays, and a few other special
cells. By recursively marking all words on free and full word
spaces which are pointed to in this manner, it is possible to
determine which words are not pointed to and are therefore garbage.
Such words are collected together on their respective free storage
lists.
(GC)
GC causes a garbage collection to occur and returns NIL.
Normally, a garbage collection occurs only when either free or full
word space has been exhausted.
(GCGAG X) flag = NIL initially.
GCGAG sets a special flag in the interpreter to the value of
X, and returns the previous setting of the flag. When any garbage
collection occurs, if the flag NE NIL, then the following is printed:
either FREE STORAGE EXHAUSTED
or FULL WORD SPACE EXHAUSTED
or nothing
followed by x FREE STORAGE, y FULL WORDS AVAILABLE
where x and y are numbers in octal.
(SPEAK)
SPEAK returns the total number of CONSes which have been
executed in this LISP core image.
(GCTIME)
GCTIME returns the number of milliseconds LISP has spent
garbage collecting in this core image.
It is possible to determine the lengths of the free and full
word free storage lists by:
(FSCNT) = length of free storage list
(FWCNT) = length of full word list
SAILON 28.7 APPENDIX E E-1
APPENDIX E
COMPILED FUNCTION LINKAGE AND ACCUMULATOR USAGE
This appendix is intended to explain the structure of
compiled functions, function calls, and accumulator usage. This
discussion is relevant only if one intends to interface hand coded
functions or possibly functions generated by another system (such as
FORTRAN) with the LISP system. In such a case, it is highly
recommended that one examine the LAP code generated by the LISP
compiler for some familiar functions.
ACCUMULATOR USAGE TABLE
s means "sacred" to the interpreter
p means "protected" during garbage collection
NIL = 0 s,p Header for the atom NIL.
A = 1 p Results from functions, 1st arg to
functions
B = 2 p 2nd arg
C = 3 p 3rd arg
AR1 = 4 p 4th arg
AR2A = 5 p 5th arg
T = 6 p used for LSUBR linkage
TT = 7 p
T10 = 10 p rarely used in the interpreter
S = 11 (*** Used for atom relocation.)
D = 12
R = 13
P = 14 s,p regular pushdown list pointer
F = 15 s,p free storage list pointer
FF = 16 s,p full word list pointer
SP = 17 s,p special pushdown list pointer.
TEMPORARY STORAGE
Whenever a LISP function is called from a compiled function,
it is assumed that all accumulators from 2 through 10 are destroyed
by the function unless it is otherwise known. Therefore, local
variables and parameters in a compiled function should be saved in
some protected cells such as the regular pushdown list. The PUSH and
POP instructions are convenient for this purpose.
SPECIAL VARIABLE BINDINGS
Special variables in compiled functions are bound to special
cells by:
SAILON 28.7 APPENDIX E E-2
PUSHJ P, SPECBIND
0 n1, var1
0 n2, var2
...
start of function code.
SPECBIND saves the previous values of var|i on the special pushdown
list and binds the contents of accumulator n|i to each var|i. The
var|i must be pointers to special cells of identifiers. Any n|i=0
causes the var|i to be bound to NIL.
Special variables are restored to their previous values by:
PUSHJ P,SPECSTR
which stores the values previously saved on the special pushdown list
in the appropriate special cells.
NUMBERS
To convert the number in A from its LISP representation to
machine representation use:
PUSHJ P,NUMVAL
which returns the value of the number in A, and its type (either
FIXNUM or FLONUM) in B.
To convert the number in A from its machine representation to
LISP representation use either:
PUSHJ P,FIX1A for FIXNUMS
or PUSHJ P,MAKNUM with type in B.
Both of the above functions return the LISP number in A.
FUNCTION CALLING UUOS
To allow ease in linking, debugging, and modifying of
compiled functions, all compiled functions call other functions with
special opcodes called UUOs. Several categories of function calls
are distinguished:
1) Calls of the form (RETURN (FOO X)) are called terminal calls
and essentially "jump" to FOO.
2) Calls of the form (F X) where F is a computed function name
or functional argument is called a functional call.
The function calling UUOS are:
SAILON 28.7 APPENDIX E E-3
non-terminal terminal
non-functional CALL n,f JCALL n,f
functional CALLF n,f JCALLF n,f
where f is either the address of a compiled function or a pointer to
the identifier for the function, and n specifies the type of function
being called as follows:
n = 0 to 5 specifies a SUBR call with n arguments
n = 16 specifies a LSUBR call
n = 17 specifies a FSUBR call.
The function calling UUOs are defined in MACRO by:
OPDEF CALL [34B8]
OPDEF JCALL [35B8]
OPDEF CALLF [36B8]
OPDEF JCALLF [37B8]
(NOUUO X) flag = T initially
NOUUO sets a special flag in the compiled function calling
mechanism to the value of X and returns the previous setting of the
flag. Compiled functions initially call other functions with function
calling UUOs which "trap" into the UUO mechanism of the interpreter.
Ordinarily, such function calls involve searching the property list
of the function being called for the functional property, and then
(depending on whether the function is compiled or an S-expression)
the function is called.
If the NOUUO flag is set to NIL, then the overhead in calling
a compiled function from a compiled function can be eliminated by
replacing the CALL by PUSHJ and JCALL by JRST. CALLF and JCALLF are
never changed.
However, there are several dangers and restrictions when
using (NOUUO NIL). Once the UUO's have been replaced by PUSHJ's then
it is not possible to redefine or TRACE the function being called.
It is therefore recommended that compiled functions be debugged with
(NOUUO T).
SUBR LINKAGE
SUBRs are compiled EXPRs which are the most common type of
function. Consequently, considerable effort has been made to make
linkage to SUBRs efficient.
Arguments to SUBRs are supplied in accumulators 1 through n,
the first argument in 1. There is a maximum of 5 arguments to SUBRs.
To call a SUBR from compiled code, use call n,FUNC, where n
is the number of arguments, and call is the appropriate UUO.
SAILON 28.7 APPENDIX E E-4
The result from a SUBR is returned in A (= 1).
FSUBR LINKAGE
FSUBRs receive one argument in A and return their result in
A. FSUBRs which use the A-LIST feature call:
PUSHJ P, *AMAKE
which generates in B a number encoding the state of the special
pushdown pointer. To call a FSUBR, use call 17, FUNC, where call is
the appropriate UUO.
LSUBR LINKAGE
LSUBRs are similar to SUBRs except that they allow an
arbitrary number of arguments to be passed. To call a LSUBR, the
following sequence is used:
PUSH P, [ret] ;return address
PUSH P, arg1 ;1st argument
...
PUSH P, argn ;nth and last argument
MOVNI T,n ;minus number of arguments
call 16,func ;the appropriate UUO
ret: ;the LSUBR returns here
When a LSUBR is entered, it executes:
JSP 3,*LCALL
which initializes the LSUBR. A will contain n. The ith argument
can be referenced by:
MOVE A, -1(P)
HRRZ A,i(A)
Exit from an LSUBR with
POPJ P,
which returns to *LCALL to restore the stack.
SAILON 28.7 APPENDIX F F-1
APPENDIX F
THE LISP COMPILER
by Whitfield Diffie
The LISP compiler is a LISP program which transforms LISP
functions defined by S-expressions into LAP assembly code. This can
be loaded into binary program space by LAP (LISP Assembly Program), a
combined assembler and loader, which produces absolute machine code
in core.
Compiled functions are approximately twenty times as fast as
interpreted functions. Compiled functions also take up less memory
space and relieve the garbage collector from marking function
definitions. In a very large system of functions, this last point is
particularly significant.
The LISP compiler exists as the system program COMPLR, and is
called by the incantation 'R COMPLR.' Once started, it is spoken to
in the same dialect as any other LISP. (*** The name is ILISPC in
UCI LISP.)
USE OF THE COMPILER
(COMPL . "FILENAME - LIST")
The function COMPL takes as arguments an assortment of file
names and device names in precisely the same way as the function
DSKIN. The default device to be used for input in the event that
none is supplied in the argument sequence is given by the value of
the variable INDEV. There is no provision for specification of an
output device in the argument sequence. If the output is wanted on
some device other than the user's disk area, the variable OUTDEV must
be set to indicate this desire. All error messages and comments are
normally directed to the teletype. They can be sent to some other
device by setting the variable LISTING. Files produced by the
compiler have the filename extension LAP.
Examples:
(COMPL FOO SYS: TRACE)
will compile the file FOO from the users disk area
and the file TRACE from the system area to produce
the files FOO.LAP and TRACE.LAP on the users disk
area.
(SETQ INDEV (QUOTE DTA2:)) (SETQ OUTDEV (QUOTE (2,123)))
(SETQ LISTING (QUOTE (DSK: CMPMSG)))
(COMPL HAT SYS: SMILE)
SAILON 28.7 APPENDIX F F-2
will compile the file HAT from DTA2: and the file
SMILE from SYS: to produce the files HAT.LAP and
SMILE.LAP on the disk area [2,123]. All compiler
messages will appear as the file CMPMSG on the
user's disk area.
PREPARING FILES FOR COMPILATION
In preparing a file for compilation there are several things
that the user is well advised to bear in mind.
1) All normal function defining functions are acceptable to the
compiler. Functions defined by DE, DF, and DEFPROP, and macros
defined by DEFPROP or DM, will be correctly understood.
2) Any function which is unknown to the compiler when it is first
obliged to generate a call thereto, will be assumed to be an EXPR or
SUBR. If a file contains a function of any other type which is
called by a function defined earlier in the file, it must be declared
to the compiler with one of the statements: (*FSUBR fun1 fun2 . . .)
or (*LSUBR fun1 fun2 . . .) so that the compiler will know how to set
up its arguments.
3) Any variable which occurs free in any function must be declared
SPECIAL prior to the definition of any function which binds it.
This may be done with a statement of the form (SPECIAL var1
var2 . . .).
4) As macros are functions which are actually executed at compile
time, their definitions must occur earlier in the file than any
function which appeals to them. If this is not done, the macro will
be mistaken for an undefined EXPR.
COMPILER MESSAGES
As the compiler goes about its business, it will make various
comments and complaints about your code.
1) As the compilation of each function is completed, its name will be
typed on the teletype without carriage return. Any other message
will be stood off by carriage returns above and below.
2) Whenever the compiler discovers a free variable which has not been
declared special, it declares it. At the end of any function in
which it found such variables it will print out the message:
(SPECIAL var1 var2 etc.).
3) If a prog variable is unused in a function the compiler will print
the message (UNUSEDPROGVAR varname). It will also declare the
variable special on the theory that if it was not used there, it must
have been used somewhere else.
SAILON 28.7 APPENDIX F F-3
4) Many minor errors in user code will unfortunately go undetected.
Any serious error will produce the message *USER ERROR* followed by a
description of what was wrong. This will halt the compiler.
5) The error message *COMPILER ERROR* indicates a bug in the compiler.
Please report this to Whitfield Diffie (R. LeFaivre at Rutgers).
6) When the compiler has finished, it will type out the name of the
file, the number of words of code produced and the time taken.
Following these will be lists of any functions called but not defined
in the file and any auxiliary functions the compiler generated.
USING COMPILED CODE
As LAP is self loading, the loading of compiled files is the
same as for interpreted functions. The allocations must be changed,
however, to reflect the passage of the code from free storage to
binary program space. The correct size of the latter is the size of
the program as stated at the end of compilation.
The following example illustrates various aspects of the
compiler's behavior. We show a collection of functions, the LAP
code generated from it, and the comments made by the compiler in the
process. (*** Somewhat different in UCI LISP.)
THE FUNCTIONS
(DM FIRST (L) (CONS @ CAR (CDR L))) ;macro defined at beginning
(DEFPROP IT T SPECIAL) ;special declaration
(DEFPROP MAPCONS ;the internal lambda
(LAMBDA (IT LIST) ;becomes a separate function
(MAPCAR (FUNCTION ;thus the variable IT must
(LAMBDA (X) ; be made special
(CONS IT X)))
LIST))
EXPR)
(DEFPROP COUNTM
(LAMBDA (SEXPR)
(PROG (COUNT) ;the variable COUNT has not been
(SETQ COUNT 0) ;declared special and will be treated
(COUNT1 SEXPR) ;as local
(RETURN COUNT)))
EXPR)
(DE COUNT1 (SS)
(COND ((ATOM SS) NIL)
(T (INCR COUNT) ;here it is discovered to be special
(COUNT1 (FIRST SS)) ;but too late
SAILON 28.7 APPENDIX F F-4
(COUNT1 (CDR SS)))))
(DE SCALE (NO) ;this variable is found to
(TIMES NO SCALEF)) ;be special, in good time
(DF SETQQ (L) (SET (CAR L) (CADR L)))
(SETQ SCALEF 3) ;this will be output unchanged
THE RESULTING LAP
;note that the macro definition and the special declaration have
;been gobbled up by the compiler.
(LAP MAPCONSG0220 SUBR) ;this is the function
(MOVE 2 (SPECIAL IT)) ;generated by the
(JCALL 2 (E XCONS)) ;internal lambda
NIL ;in MAPCONS
(LAP MAPCONS SUBR)
(JSP 6 SPECBIND)
(0 2 (SPECIAL IT))
(MOVEI 1 (QUOTE MAPCONSG0220))
(CALL 2 (E MAPCAR))
(JRST 0 SPECSTR)
NIL
(LAP COUNTM SUBR)
(PUSH P 1) ;this code is in error
(PUSH P (C 0 0 (QUOTE 0) 0)) ;due to the failure
(CALL 1 (E COUNT1)) ;to make COUNT special
(MOVE 1 0 P)
(SUB P (C 0 0 2 2))
(POPJ P)
NIL
(LAP COUNT1 SUBR)
(PUSH P 1)
(CALL 1 (E ATOM))
(JUMPE 1 G0229)
(MOVEI 1 (QUOTE NIL))
(JRST 0 G0228)
G0229 (MOVE 1 (SPECIAL COUNT)) ;reference to the special
(CALL 1 (E INCR)) ;variable COUNT, which has
(HLRZ@ 1 0 P) ;not been bound properly
(CALL 1 (E COUNT1))
(HRRZ@ 1 0 P)
(CALL 1 (E COUNT1))
G0228 (SUB P (C 0 0 1 1))
(POPJ P)
NIL
SAILON 28.7 APPENDIX F F-5
(LAP SCALE SUBR)
(MOVE 2 (SPECIAL SCALEF)) ;SCALEF is a free variable
(JCALL 2 (E *TIMES)) ;correctly detected
NIL
(LAP SETQQ FSUBR)
(HRRZ@ 2 1)
(HLRZ@ 2 2)
(HLRZ@ 1 1)
(JCALL 2 (E SET))
NIL
(SETQ SCALEF 3) ;this was unchanged by compilation
THE COMPILER'S OPINION
MAPCONSG0220 MAPCONS COUNTM
(SPECIAL COUNT) ;special found too late
COUNT1
(SPECIAL SCALEF) ;special found in time
SCALE SETQQ
(CMP . CMP) COMPILED 41 WORDS 3 CONSTANTS 1 SECONDS
UNDEFINED FUNCTIONS
INCR
GENERATED FUNCTIONS
MAPCONSG0220
SAILON 28.7 APPENDIX G G-1
APPENDIX G
THE LISP ASSEMBLER - LAP
LAP is a primitive assembler designed to load the output of the
compiler. Normally, it is not necessary to use LAP for any other purpose.
LAP is self loading.
The format of a compiled function in LAP is:
(LAP name type)
<sequence of LAP instructions>
NIL
where name is the name of the function, and type is either SUBR, LSUBR,
or FSUBR.
A LAP instruction is either:
1. A label which is a non-NIL identifier.
2. A list of the form
(OPCODE AC ADDR INDEX)
a. The index field is optional.
b. The opcode is either a PDP-6/10 instruction
which is defined to LAP and optionally suffixed
by @ which designates indirect addressing, or
a number which specifies a numerical opcode.
c. The AC and INDEX fields should contain a number
from 0 to 17, or P which designates register 14.
d. The ADDR field may be a number, a label, or a
list of one of the following forms:
(QUOTE S-expression) to reference list structure.
(SPECIAL x) to reference the value of
identifier x.
(E f) to reference the function f.
(C OPCODE AC ADDR INDEX) to reference a literal
constant.
For example, the function ABS could be defined:
SAILON 28.7 APPENDIX G G-2
(LAP ABS SUBR)
(CALL 1 (E NUMVAL))
(MOVMS 0 1)
(JCALL 2(E MAKNUM))
NIL
SAILON 28.7 APPENDIX H H-1
APPENDIX H
THE LOADER
A modified version of the standard PDP-6/10
MACRO-FAIL-FORTRAN loader is available for use in LISP. One can call
the loader into a LISP core image at any time by executing:
(LOAD X)
When a * is typed, you are in the (LOAD X) loader, and the loader
command strings are expected. As soon as an altmode is typed, the
loader finishes and exits back to LISP.
The loader is placed in expanded core. If X = NIL then
loaded programs are placed in expanded core, otherwise (if X NE NIL)
they are placed in BINARY PROGRAM SPACE.
The loader removes itself and contracts core when it is
finished. In the following discussion a "RELOC" program will refer to
any program which is suitable for loading with the loader. The
output of FORTRAN, MACRO or FAIL is a RELOC program.
(EXCISE)
EXCISE contracts core to its length after ALLOCATION or the
last START. This removes I/O buffers, and all RELOC programs.
(*GETSYM S)
*GETSYM searches the DDT symbol table for the symbol S and if
found returns its value, otherwise it returns NIL.
(GETSYM "P" "S|1" "S|2" ... "S|n")
GETSYM searches the DDT symbol table for each of the symbols
S|i and places the value on the property list of S|i under property P.
Example: (GETSYM SUBR DDT)
This causes DDT to be defined as a SUBR located at the value
of the symbol DDT.
Note: In order to load the symbol table, either /S or /D must be
typed to the loader. Symbols which are declared INTERNAL are
always in the symbol table without the /S or /D. In the case
of multiply defined symbols, i.e., a symbol used in more than
one RELOC program, a symbol declared INTERNAL takes
precedence, the last symbol otherwise.
SAILON 28.7 APPENDIX H H-2
(*PUTSYM S V)
*PUTSYM enters the symbol S into the DDT symbol table with
value V.
(PUTSYM "X|1" "X|2" ..."X|n")
PUTSYM is used to place symbols in the DDT symbol table. If
X|i is an atom then the symbol X|i is placed in the symbol table with
its value pointing to the atom X|i. If X|i is a list, the symbol in
(CAR X|i) is placed in the symbol table with its value (EVAL (CADR
X|i)). PUTSYM is useful for making LISP atoms, functions, and
variables available to RELOC programs. Symbols must be defined with
PUTSYM before the LOADER is used.
Examples: (PUTSYM BPORG (VBPORG (GET (QUOTE BPORG)(QUOTE VALUE))))
defines the identifier BPORG and its value cell VBPORG. A RELOC
program can reference the value of BPORG by:
MOVE X,VBPORG
(PUTSYM (MAPLST (QUOTE MAPLST)) (NUMBERP (QUOTE NUMBERP)))
(PUTSYM (MEMQ (GET(QUOTE MEMQ) (QUOTE SUBR))))
A RELOC program would call these functions as follows:
CALL 2,MAPLST
CALL 1,NUMBRP
PUSHJ P,MEMQ or CALL 2,MEMQ
An example of a simple LISP compatible MACRO program to
compute square roots using the FORTRAN library.
TITLE TEST
P=14
A=1
B=2
EXTERN MAKNUM,NUMVAL,SQRT,FLONUM
LSQRT: CALL 1, NUMVAL
MOVEM A,AR1
MOVE A,[XWD 0,BLT1]; SAVE THE AC'S
BLT A,BLT1+17
JSA 16,SQRT
JUMP 2,AR1 ;SOP TO FORTRAN
MOVE 0,AR1
MOVE A,[XWD BLT1 ,0]
BLT A,17
MOVE A,AR1
MOVEI B,FLONUM
JCALL 2,MAKNUM
AR1: 0
BLT1: BLOCK 20
END
SAILON 28.7 APPENDIX I I-1
APPENDIX I
BIGNUMS - ARBITRARY PRECISION INTEGERS
(*** Not available in UCI LISP.)
SAILON 28.7 APPENDIX J J-1
A USER MODIFIABLE LISP SCANNER
by Lynn Quam
LISP uses a table driven scanner, whose table may be modified
by the user for the purpose of implementing scanners for other
languages. For simplicity, the functions for constructing the scanner
table initially give an ALGOL type scanner, that is the ALGOL
definitions for identifiers, strings and numbers (except for powers
of ten). The ALGOL table may be modified by using additional
functions to include additional characters in identifiers, and to
specify delimiters for strings.
J.1 FORMAL DEFINITIONS
J.1.1 Identifiers
Syntax:
comment ::= (a comment-start followed by any sequence of
characters ending in a comment-end)
digit ::= "0" | "1" | ... | "9"
letter ::= "A" | "B" | ... | "Z" | "a" | "b" | ... | "z" |
extra-letter
character ::= (any ASCII character other than null, rubout,
and comment-start)
delimiter ::= (any character not a letter and not a digit)
::= letter
::= identifier digit
::= identifier letter
::= slashified character
::= identifier slashified character
Semantics:
In the above syntax, underlined symbols can be specified by
the user. For instance, comment-start and comment-end could both be
specified to be double quote ("). If it is desirable to include
dollar and percent signs in identifiers, then both of these
characters should be extra-letters. Slashifiers make it possible to
include any delimiter in an identifier. For example, if question
mark is the slashifier (?) and it is desirable to include the
character (+) in the identifier V as V+, then one should slashify the
plus: V?+.
J.1.2 Strings
Syntax:
string ::= (a string-start followed by any sequence of
characters ending in a string-end)
SAILON 28.7 APPENDIX J J-2
Semantics:
String-start and string-end are specifiable.
J.1.3 Numbers
Syntax:
Same as specified in Chapter 4, except that leading signs (+
or -) in numbers are treated as delimiters.
J.2 DESCRIPTIONS OF THE SCANNER MODIFYING FUNCTIONS
In the following descriptions, all characters are specified
by their numerical ASCII value. For example, in octal, blank is 40
and A is 101.
(SCANINIT comment-start comment-end string-start string-end slashifier)
SCANINIT modifies the LISP scanner to be an ALGOL-type
scanner with special delimiters for comments and strings. SCANINIT
must be called before any of the other scanner functions.
(IGNORE x)
LETTER specifies to the scanner that x is not to be returned
as a delimiter from scan, but instead will be ignored. However, x
will still function as a separator between identifier and numbers.
For example, carriage-return, line-feed, tab and blank are useful
characters to ignore as delimiters.
(LETTER X)
Letter specifies to the scanner that X is an extra-letter,
and thus allows X to be in an identifier.
(SCAN)
SCAN reads an atom or delimiter and sets the value of the
global variable SCNVAL to the value read, and returns a number
corresponding to the syntactic type read as follows:
Syntactic type Value of SCAN Value of SCNVAL
identifier 0 the uninterned identifier
string 1 the string
number 2 the value
delimiter 3 the ASCII value of the
delimiter.
(SCANSET)
SCANSET modifies the LISP scanner in READ according to the
user specifications. Evaluate (SCANSET) before calling SCAN.
SAILON 28.7 APPENDIX J J-3
(SCANRESET)
SCANRESET unmodifies the LISP scanner to its normal state,
and must be called before READ will work properly again once SCANSET
is used. Use INITFN to call SCANRESET after errors.
J.3 USING THE MODIFIABLE SCANNER
The scanner modifying functions are not a normal part of the
LISP system and must be explicitly loaded into a LISP core image.
The following steps indicate how to provide the proper interface
between LISP and the scanner, load the scanner, and initialize the
scanner tables.
(SETQ SCNVAL NIL)
(RPUTSYM (SCNVAL (GET @SCNVAL @VALUE))) (*** For UCI LISP)
(LOAD) LSP:SCAN$
(GETSYM SUBR SCANINIT LETTER IGNORE SCAN SCANSET
SCANRESET)
(SCANINIT 21 73 42 42 45)
<this makes comments start with ↑Q and end with semicolon,
strings start and end with double quotes ("), and
percent (%) is the slashifier>
To use the scanner, one must first call the SCANSET. Once
SCANSET has been called, the normal LISP function READ no longer
behaves in a normal fashion, since READ will now use the modified
scanner tables. Care must be taken to call SCANRESET before calling
READ.
SAILON 28.7 APPENDIX K K-1
APPENDIX K
SOS-LINK
by Whitfield Diffie
(*** Not available in UCI LISP.)
SAILON 28.7 APPENDIX L L-1
APPENDIX L
SOME DIFFERENCES BETWEEN THIS AND OTHER LISPS
by Whitfield Diffie
1) The top level of this system does not use EVALQUOTE as do many
systems. However, EVALQUOTE may be defined as follows:
(DE EVALQUOTE NIL
(PROG NIL
L (TERPRI)
(PRINT (EVAL (CONS (READ) (MAPCAR
(FUNCTION (LAMBDA (X) (LIST (QUOTE QUOTE) X)))
(READ)))))
(GO L)))
The top level of LISP 1.6 is equivalent to:
(PROG NIL
L (TERPRI)
(PRINT (EVAL (READ)))
(GO L))
2) The order of the arguments in the various functions
MAP, MAPCAR etc. is function first, list second,
rather that the reverse as in many systems.
3) There are certain differences even between Stanford
Lisp and other DEC system Lisps.
a) the comment character is ascii 31
b) project programmer numbers are pairwords
in which each half holds up to three
right adjusted sixbit characters.
SAILON 28.7 REFERENCES REF-1
REFERENCES
1. John McCarthy, et al., LISP 1.5 Programmer's Manual
(Cambridge, Mass., MIT Press, 1962).
2. Clark Weissman, LISP 1.5 Primer, (Dickenson Publishing
Co., 1967).
3. Robert A. Saunders, "LISP - On the Programming System",
in Edmond C. Berkley and Daniel G. Bobrow (eds.),
The Programming Language LISP: Its Operation and
Applications, 2nd edition, (Cambridge, Mass., The
MIT Press, 1966), p.54.
SAILON 28.7 INDEX IND-1
INDEX
ABS SUBR . . . . . . . . . . . . . . . . 12-1
ADD1 SUBR . . . . . . . . . . . . . . . . 12-1
ALIST . . . . . . . . . . . . . . . . 7-3
AND FSUBR . . . . . . . . . . . . . . . . 9-3
APPEND LSUBR n arguments . . . . . . . . . . 10-1
APPLY LSUBR . . . . . . . . . . . . . . . . 7-1
ARG SUBR . . . . . . . . . . . . . . . . 6-2
ARRAY FSUBR different . . . . . . . . . . . 15-1
ASCII SUBR . . . . . . . . . . . . . . . . 11-3
ASSOC SUBR uses EQ . . . . . . . . . . . . 10-6
ATOM SUBR . . . . . . . . . . . . . . 3-1,9-1
BASE VALUE initialized to 8 . . . . . . . 4-1
BOOLE LSUBR . . . . . . . . . . . . . . . . 12-3
CAR SUBR . . . . . . . . . . . . . . . . 10-2
CDR SUBR . . . . . . . . . . . . . . . . 10-2
... ... . . . . . . . . . . . . . . . .
CAAAAR SUBR . . . . . . . . . . . . . . . . 10-2
CDDDDR SUBR . . . . . . . . . . . . . . . . 10-2
CHRCT SUBR . . . . . . . . . . . . . . . . 14-5
COND FSUBR allows more than one consequent 8-1
CONS SUBR . . . . . . . . . . . . . . . . 10-1
CSYM FSUBR . . . . . . . . . . . . . . . . 11-3
DDTIN SUBR . . . . . . . . . . . . . . . . 14-3
DDTOUT SUBR . . . . . . . . . . . . . . . . 14-5
DE FSUBR . . . . . . . . . . . . . . . . 11-2
DEFPROP FSUBR . . . . . . . . . . . . . . . . 11-2
DEPOSIT SUBR . . . . . . . . . . . . . . . . 15-2
DF FSUBR . . . . . . . . . . . . . . . . 11-2
DIFFERENCE MACRO n arguments . . . . . . . . . . 12-1
DIVIDE SUBR . . . . . . . . . . . . . . . . 12-1
DM FSUBR . . . . . . . . . . . . . . . . 11-2
DSKIN FEXPR . . . . . . . . . . . . . . . . 14-2
EQ SUBR . . . . . . . . . . . . . . . . 9-1
EQUAL SUBR . . . . . . . . . . . . . . . . 9-1
ERR SUBR . . . . . . . . . . . . . . . . 16-1
ERRSET FSUBR . . . . . . . . . . . . . . . . 16-1
EVAL LSUBR second argument allowed . . . . 7-1
EXAMINE SUBR . . . . . . . . . . . . . . . . 15-2
EXARRAY FSUBR . . . . . . . . . . . . . . . . 15-2
EXCISE SUBR . . . . . . . . . . . . . . . . H-1
EXPLODE SUBR . . . . . . . . . . . . . . . . 10-6
EXPLODEC SUBR . . . . . . . . . . . . . . . . 10-7
SAILON 28.7 INDEX IND-2
EXPR . . . . . . . . . . . . . . . . 6-2
FEXPR . . . . . . . . . . . . . . . . 6-2
FILENAMES . . . . . . . . . . . . . . . . 14-1
FIX SUBR . . . . . . . . . . . . . . . . 12-2
FIX1A SYM . . . . . . . . . . . . . . . . E-2
FIXNUM . . . . . . . . . . . . . . . . 4-2
FLATSIZE SUBR . . . . . . . . . . . . . . . . 10-7
FLONUM . . . . . . . . . . . . . . . . 4-3
FSUBR . . . . . . . . . . . . . . . . E-4
FUNARG . . . . . . . . . . . . . . . . 7-4
FUNCTION FSUBR . . . . . . . . . . . . . . . . 7-1
FUNCTIONAL ARGUMENTS . . . . . . . . . . . . . . . 7-1
GC SUBR . . . . . . . . . . . . . . . . D-1
GCD SUBR . . . . . . . . . . . . . . . . 12-1
GCGAG SUBR . . . . . . . . . . . . . . . . D-1
GCTIME SUBR . . . . . . . . . . . . . . . . D-1
GENSYM SUBR . . . . . . . . . . . . . . . . 11-3
GET SUBR . . . . . . . . . . . . . . . . 11-1
GETL SUBR . . . . . . . . . . . . . . . . 11-1
GETSYM FEXPR . . . . . . . . . . . . . . . . H-1
GO FSUBR . . . . . . . . . . . . . . . . 13-1
GREATERP MACRO n arguments . . . . . . . . . . 9-3
IBASE VALUE initialized to 8 . . . . . . . 4-1
IDENTIFIER . . . . . . . . . . . . . . . . 3-1
INC SUBR . . . . . . . . . . . . . . . . 14-1
INITFN SUBR . . . . . . . . . . . . . . . . 16-1
INPUT FSUBR . . . . . . . . . . . . . . . . 14-1
INTEGER . . . . . . . . . . . . . . . . 4-1
INTERN SUBR . . . . . . . . . . . . . . . . 11-2
LABEL . . . . . . . . . . . . . . . . 6-1
LAMBDA . . . . . . . . . . . . . . . . 6-1
LAST SUBR returns end of list . . . . . . 10-2
LENGTH SUBR . . . . . . . . . . . . . . . . 10-4
LESSP MACRO n arguments . . . . . . . . . . 9-3
LEXPR . . . . . . . . . . . . . . . . 6-2
LINELENGTH SUBR . . . . . . . . . . . . . . . . 14-5
LIST FSUBR . . . . . . . . . . . . . . . . 10-1
LOAD SUBR . . . . . . . . . . . . . . . . H-1
LSH SUBR . . . . . . . . . . . . . . . . 12-3
LSUBR . . . . . . . . . . . . . . . . E-4
MACRO . . . . . . . . . . . . . . . . 6-3
MAKNAM SUBR . . . . . . . . . . . . . . . . 10-7
MAKNUM SUBR . . . . . . . . . . . . . . . . E-2
MAP SUBR different argument order. . . . 10-5
MAPC SUBR " " " . . . 10-5
MAPCAR SUBR " " " . . . 10-6
MAPLIST SUBR " " " . . . 10-5
MEMBER SUBR uses EQUAL . . . . . . . . . . 9-2
MEMQ SUBR uses EQ . . . . . . . . . . . . 9-2
SAILON 28.7 INDEX IND-3
MINUS SUBR . . . . . . . . . . . . . . . . 12-1
MINUSP SUBR . . . . . . . . . . . . . . . . 9-2
NCONC LSUBR . . . . . . . . . . . . . . . . 10-3
NCONS SUBR . . . . . . . . . . . . . . . . 10-1
NIL VALUE initialized to NIL . . . . . . 5-1
NOT SUBR . . . . . . . . . . . . . . . . 9-3
NOUUO SUBR initialized to T . . . . . . . E-3
NULL SUBR . . . . . . . . . . . . . . . . 9-2
NUMBER . . . . . . . . . . . . . . . . 4-1
NUMBERP SUBR . . . . . . . . . . . . . . . . 9-2
NUMVAL SUBR . . . . . . . . . . . . . . . . E-2
OBLIST VALUE . . . . . . . . . . . . . . . . 3-3
OR FSUBR . . . . . . . . . . . . . . . . 9-3
OUTC SUBR . . . . . . . . . . . . . . . . 14-5
OUTPUT FSUBR . . . . . . . . . . . . . . . . 14-5
PLUS MACRO n arguments . . . . . . . . . . 12-1
PNAME . . . . . . . . . . . . . . . . 3-2
PRIN1 SUBR allows non-atomic S-expressions 14-5
PRINC SUBR . . . . . . . . . . . . . . . . 14-6
PRINT SUBR TERPRI first . . . . . . . . . 14-6
PROG FSUBR . . . . . . . . . . . . . . . . 13-1
PROG2 SUBR allows up to 5 arguments. . . . 13-1
PROPERTY LIST . . . . . . . . . . . . . . . . 3-2
PUTPROP SUBR order of arguments different 11-1
PUTSYM FEXPR . . . . . . . . . . . . . . . . H-2
QUOTE FSUBR . . . . . . . . . . . . . . . . 7-1
QUOTIENT MACRO n arguments . . . . . . . . . . 12-1
READ SUBR . . . . . . . . . . . . . . . . 14-3
READCH SUBR . . . . . . . . . . . . . . . . 14-4
READLIST SUBR . . . . . . . . . . . . . . . . 10-7
REMAINDER SUBR . . . . . . . . . . . . . . . . 12-1
REMOB FSUBR . . . . . . . . . . . . . . . . 11-2
REMPROP SUBR . . . . . . . . . . . . . . . . 11-1
RETURN SUBR . . . . . . . . . . . . . . . . 13-1
REVERSE SUBR . . . . . . . . . . . . . . . . 10-4
RPLACA SUBR . . . . . . . . . . . . . . . . 10-3
RPLACD SUBR . . . . . . . . . . . . . . . . 10-3
SASSOC SUBR uses EQ . . . . . . . . . . . . 10-6
SET SUBR . . . . . . . . . . . . . . . . 11-2
SETARG SUBR . . . . . . . . . . . . . . . . 6-3
SETQ FSUBR . . . . . . . . . . . . . . . . 11-2
SEXPRESSION . . . . . . . . . . . . . . . . 5-1
SPEAK SUBR . . . . . . . . . . . . . . . . D-1
SPECBIND SYM . . . . . . . . . . . . . . . . E-2
SPECSTR SYM . . . . . . . . . . . . . . . . E-2
SPECIAL not in interpreter . . . . . . F-1
SPECIAL VARIABLES . . . . . . . . . . . . . . . . 7-3
STORE FSUBR . . . . . . . . . . . . . . . . 15-2
STRING . . . . . . . . . . . . . . . . 3-3
SAILON 28.7 INDEX IND-4
SUB1 SUBR . . . . . . . . . . . . . . . . 12-1
SUBR . . . . . . . . . . . . . . . . E-3
SUBST SUBR . . . . . . . . . . . . . . . . 10-4
T VALUE initialized to T . . . . . . . 9-1
TERPRI SUBR . . . . . . . . . . . . . . . . 14-6
TIME SUBR . . . . . . . . . . . . . . . . 16-1
TIMES MACRO n arguments . . . . . . . . . . 12-1
TYI SUBR . . . . . . . . . . . . . . . . 14-4
TYO SUBR . . . . . . . . . . . . . . . . 14-6
VALUE . . . . . . . . . . . . . . . . 3-2
VARIABLE BINDINGS . . . . . . . . . . . . . . . . 7-2
XCONS SUBR . . . . . . . . . . . . . . . . 10-1
ZEROP SUBR . . . . . . . . . . . . . . . . 9-2
$EOF$ . . . . . . . . . . . . . . . . 14-2
*AMAKE SYM . . . . . . . . . . . . . . . . E-4
*APPEND SUBR . . . . . . . . . . . . . . . . 10-1
*DIF SUBR . . . . . . . . . . . . . . . . 12-1
*EVAL SUBR . . . . . . . . . . . . . . . . 7-1
*EXPAND SUBR . . . . . . . . . . . . . . . . 6-4
*EXPAND1 SUBR . . . . . . . . . . . . . . . . 6-4
*FUNCTION FSUBR . . . . . . . . . . . . . . . . 7-4
*GETSYM SUBR . . . . . . . . . . . . . . . . H-1
*GREAT SUBR . . . . . . . . . . . . . . . . 9-3
*LCALL SYM . . . . . . . . . . . . . . . . E-4
*LESS SUBR . . . . . . . . . . . . . . . . 9-3
*NOPOINT VALUE initialized to NIL . . . . . . 4-1
*PLUS SUBR . . . . . . . . . . . . . . . . 12-1
*PUTSYM SUBR . . . . . . . . . . . . . . . . H-2
*QUO SUBR . . . . . . . . . . . . . . . . 12-1
*RSET SUBR initialized to NIL . . . . . . 16-1
*TIMES SUBR . . . . . . . . . . . . . . . . 12-1